[Libva] [Libva-intel-driver PATCH 2/9] Wrapper the DriverContextP of backend driver

Zhao Yakui yakui.zhao at intel.com
Sat Sep 5 18:39:09 PDT 2015


The default directory of backend driver is used.(LIBVA_DRIVERS_PATH).
Only when the backend driver exists, the wrapper is initialized and added.
Otherwise it won't be initialized.

And the option of "enable-wrapper" is added, which is used to determine whether
the wrapper of backend driver is supported.

Signed-off-by: Zhao Yakui <yakui.zhao at intel.com>
Signed-off-by: Sean V Kelley <seanvk at posteo.de>
---
 configure.ac         |  11 ++++
 src/Makefile.am      |   1 +
 src/i965_drv_video.c | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/i965_drv_video.h |   2 +
 4 files changed, 160 insertions(+)

diff --git a/configure.ac b/configure.ac
index 6e73059..b118441 100644
--- a/configure.ac
+++ b/configure.ac
@@ -56,6 +56,11 @@ AC_ARG_ENABLE([wayland],
                     [build with VA/Wayland API support @<:@default=yes@:>@])],
     [], [enable_wayland="yes"])
 
+AC_ARG_ENABLE([wrapper],
+    [AC_HELP_STRING([--enable-wrapper],
+                    [build with hybrid_wrapper support @<:@default=no@:>@])],
+    [], [enable_wrapper="no"])
+
 AC_DISABLE_STATIC
 AC_PROG_LIBTOOL
 AC_PROG_CC
@@ -107,6 +112,12 @@ if test "$USE_DRM" = "yes"; then
 fi
 AM_CONDITIONAL(USE_DRM, test "$USE_DRM" = "yes")
 
+USE_WRAPPER="no"
+if test "$enable_wrapper" = "yes"; then
+    USE_WRAPPER="yes"
+    AC_DEFINE([HAVE_USE_WRAPPER], [1], [Defined to 1 if hybrid_wrapper is needed])
+fi
+
 VA_VERSION=`$PKG_CONFIG --modversion libva`
 VA_MAJOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f1`
 VA_MINOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f2`
diff --git a/src/Makefile.am b/src/Makefile.am
index dc82c43..a170aee 100755
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -29,6 +29,7 @@ AM_CPPFLAGS = \
 	-DPTHREADS		\
 	$(DRM_CFLAGS)		\
 	$(LIBVA_DEPS_CFLAGS)	\
+	-DVA_DRIVERS_PATH="\"$(LIBVA_DRIVERS_PATH)\"" \
 	$(NULL)
 
 driver_cflags = \
diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c
index b0fb7d6..b43c726 100644
--- a/src/i965_drv_video.c
+++ b/src/i965_drv_video.c
@@ -29,6 +29,7 @@
 
 #include "sysdeps.h"
 #include <unistd.h>
+#include <dlfcn.h>
 
 #ifdef HAVE_VA_X11
 # include "i965_output_dri.h"
@@ -5732,6 +5733,133 @@ error:
     return false;
 }
 
+/* Only when the option of "enable-wrapper" is passed, it is possible
+ * to initialize/load the wrapper context of backend driver.
+ * Otherwise it is not loaded.
+ */
+#if HAVE_USE_WRAPPER
+
+static VAStatus
+i965_initialize_wrapper(VADriverContextP ctx, const char *driver_name)
+{
+#define DRIVER_EXTENSION	"_drv_video.so"
+
+    struct i965_driver_data *i965 = i965_driver_data(ctx);
+
+    VADriverContextP wrapper_pdrvctx;
+    struct VADriverVTable *vtable;
+    char *search_path, *driver_dir;
+    char *saveptr;
+    char driver_path[256];
+    void *handle = NULL;
+    VAStatus va_status = VA_STATUS_SUCCESS;
+    bool driver_loaded = false;
+
+    if (!(IS_HASWELL(i965->intel.device_info) ||
+          IS_GEN8(i965->intel.device_info) ||
+          IS_GEN9(i965->intel.device_info))) {
+        return VA_STATUS_ERROR_UNIMPLEMENTED;
+    }
+
+    wrapper_pdrvctx = calloc(1, sizeof(*wrapper_pdrvctx));
+    vtable = calloc(1, sizeof(*vtable));
+
+    if (!wrapper_pdrvctx || !vtable) {
+        fprintf(stderr, "Failed to allocate memory for wrapper \n");
+        free(wrapper_pdrvctx);
+        free(vtable);
+        return VA_STATUS_ERROR_ALLOCATION_FAILED;
+    }
+
+    /* use the same drm_state with CTX */
+    wrapper_pdrvctx->drm_state = ctx->drm_state;
+    wrapper_pdrvctx->display_type = ctx->display_type;
+    wrapper_pdrvctx->vtable = vtable;
+
+    search_path = VA_DRIVERS_PATH;
+    search_path = strdup((const char *)search_path);
+
+    driver_dir = strtok_r(search_path, ":", &saveptr);
+    while (driver_dir && !driver_loaded) {
+        memset(driver_path, 0, sizeof(driver_path));
+        sprintf(driver_path, "%s/%s%s", driver_dir, driver_name, DRIVER_EXTENSION);
+
+        if (access(driver_path, F_OK)) {
+            driver_dir = strtok_r(NULL, ":", &saveptr);
+            continue;
+        }
+
+        handle = dlopen(driver_path, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
+        if (!handle) {
+            fprintf(stderr, "failed to open %s\n", driver_path);
+            driver_dir = strtok_r(NULL, ":", &saveptr);
+            continue;
+        }
+        {
+            VADriverInit init_func = NULL;
+            char init_func_s[256];
+            int i;
+
+            static const struct {
+                int major;
+                int minor;
+            } compatible_versions[] = {
+                { VA_MAJOR_VERSION, VA_MINOR_VERSION },
+                { 0, 37 },
+                { 0, 36 },
+                { 0, 35 },
+                { 0, 34 },
+                { 0, 33 },
+                { 0, 32 },
+                { -1, }
+            };
+            for (i = 0; compatible_versions[i].major >= 0; i++) {
+                snprintf(init_func_s, sizeof(init_func_s),
+                     "__vaDriverInit_%d_%d",
+                     compatible_versions[i].major,
+                     compatible_versions[i].minor);
+                init_func = (VADriverInit)dlsym(handle, init_func_s);
+                if (init_func) {
+                    break;
+                }
+            }
+            if (compatible_versions[i].major < 0) {
+                dlclose(handle);
+                fprintf(stderr, "%s has no function %s\n",
+                            driver_path, init_func_s);
+                driver_dir = strtok_r(NULL, ":", &saveptr);
+                continue;
+            }
+
+            if (init_func)
+                va_status = (*init_func)(wrapper_pdrvctx);
+
+            if (va_status != VA_STATUS_SUCCESS) {
+                dlclose(handle);
+                fprintf(stderr, "%s init failed\n", driver_path);
+                driver_dir = strtok_r(NULL, ":", &saveptr);
+                continue;
+            }
+
+            wrapper_pdrvctx->handle = handle;
+            driver_loaded = true;
+        }
+    }
+
+    free(search_path);
+
+    if (driver_loaded) {
+        i965->wrapper_pdrvctx = wrapper_pdrvctx;
+        return VA_STATUS_SUCCESS;
+    } else {
+        fprintf(stderr, "Failed to wrapper %s%s\n", driver_name, DRIVER_EXTENSION);
+        free(vtable);
+        free(wrapper_pdrvctx);
+        return VA_STATUS_ERROR_OPERATION_FAILED;
+    }
+}
+#endif
+
 static VAStatus 
 i965_Init(VADriverContextP ctx)
 {
@@ -5764,6 +5892,10 @@ i965_Init(VADriverContextP ctx)
         if (i965->codec_info && i965->codec_info->preinit_hw_codec)
             i965->codec_info->preinit_hw_codec(ctx, i965->codec_info);
 
+#if HAVE_USE_WRAPPER
+        i965_initialize_wrapper(ctx, "hybrid");
+#endif
+
         return VA_STATUS_SUCCESS;
     } else {
         i--;
@@ -5785,6 +5917,19 @@ i965_Terminate(VADriverContextP ctx)
     struct i965_driver_data *i965 = i965_driver_data(ctx);
     int i;
 
+    if (i965->wrapper_pdrvctx) {
+       VADriverContextP pdrvctx;
+       pdrvctx = i965->wrapper_pdrvctx;
+       if (pdrvctx->handle) {
+           pdrvctx->vtable->vaTerminate(pdrvctx);
+           dlclose(pdrvctx->handle);
+           pdrvctx->handle = NULL;
+       }
+       free(pdrvctx->vtable);
+       free(pdrvctx);
+       i965->wrapper_pdrvctx = NULL;
+    }
+
     if (i965) {
         for (i = ARRAY_ELEMS(i965_sub_ops); i > 0; i--)
             if (i965_sub_ops[i - 1].display_type == 0 ||
@@ -5883,6 +6028,7 @@ VA_DRIVER_INIT_FUNC(  VADriverContextP ctx )
         return VA_STATUS_ERROR_ALLOCATION_FAILED;
     }
 
+    i965->wrapper_pdrvctx = NULL;
     ctx->pDriverData = (void *)i965;
     ret = i965_Init(ctx);
 
diff --git a/src/i965_drv_video.h b/src/i965_drv_video.h
index 84b557e..de71221 100644
--- a/src/i965_drv_video.h
+++ b/src/i965_drv_video.h
@@ -424,6 +424,8 @@ struct i965_driver_data
 
     /* VA/Wayland specific data */
     struct va_wl_output *wl_output;
+
+    VADriverContextP wrapper_pdrvctx;
 };
 
 #define NEW_CONFIG_ID() object_heap_allocate(&i965->config_heap);
-- 
1.8.4.2



More information about the Libva mailing list