summaryrefslogtreecommitdiff
path: root/libraries/libvdpau/patches/vdpau_wrapper_c.patch
blob: e32fc120a500a873b5d878893450d8e04c3d3a34 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
From 4262513e67c3572ed19bd796ec6180cdde7ccb7e Mon Sep 17 00:00:00 2001
From: Kiran Pawar <kpawar@nvidia.com>
Date: Fri, 05 Aug 2011 06:15:18 +0000
Subject: vdpau_wrapper.c: Track dynamic library handles and free them on exit using __attribute__((destructor))

Signed-off-by: Kiran Pawar <kpawar@nvidia.com>
Tested-by: Aaron Plattner <aplattner@nvidia.com>
Signed-off-by: Aaron Plattner <aplattner@nvidia.com>
---
diff --git a/src/vdpau_wrapper.c b/src/vdpau_wrapper.c
index f504775..23de3d4 100644
--- a/src/vdpau_wrapper.c
+++ b/src/vdpau_wrapper.c
@@ -40,6 +40,17 @@ typedef void SetDllHandle(
     void * driver_dll_handle
 );
 
+static void * _vdp_backend_dll;
+static void * _vdp_trace_dll;
+static void * _vdp_driver_dll;
+static VdpDeviceCreateX11 * _vdp_imp_device_create_x11_proc;
+
+#if defined(__GNUC__)
+
+static void _vdp_close_driver(void) __attribute__((destructor));
+
+#endif
+
 #if DEBUG
 
 static void _vdp_wrapper_error_breakpoint(char const * file, int line, char const * function)
@@ -87,23 +98,16 @@ static char * _vdp_get_driver_name_from_dri2(
     return driver_name;
 }
 
-VdpStatus vdp_device_create_x11(
+static VdpStatus _vdp_open_driver(
     Display *             display,
-    int                   screen,
-    /* output parameters follow */
-    VdpDevice *           device,
-    VdpGetProcAddress * * get_proc_address
-)
+    int                   screen)
 {
     char const * vdpau_driver;
     char * vdpau_driver_dri2 = NULL;
     char         vdpau_driver_lib[PATH_MAX];
-    void *       backend_dll;
     char const * vdpau_trace;
     char const * func_name;
 
-    VdpDeviceCreateX11 * vdp_imp_device_create_x11;
-
     vdpau_driver = getenv("VDPAU_DRIVER");
     if (!vdpau_driver) {
         vdpau_driver = vdpau_driver_dri2 =
@@ -125,13 +129,13 @@ VdpStatus vdp_device_create_x11(
         return VDP_STATUS_NO_IMPLEMENTATION;
     }
 
-    backend_dll = dlopen(vdpau_driver_lib, RTLD_NOW | RTLD_GLOBAL);
-    if (!backend_dll) {
+    _vdp_driver_dll = dlopen(vdpau_driver_lib, RTLD_NOW | RTLD_GLOBAL);
+    if (!_vdp_driver_dll) {
         /* Try again using the old path, which is guaranteed to fit in PATH_MAX
          * if the complete path fit above. */
         snprintf(vdpau_driver_lib, sizeof(vdpau_driver_lib), DRIVER_LIB_FORMAT,
                  "", vdpau_driver, "");
-        backend_dll = dlopen(vdpau_driver_lib, RTLD_NOW | RTLD_GLOBAL);
+        _vdp_driver_dll = dlopen(vdpau_driver_lib, RTLD_NOW | RTLD_GLOBAL);
     }
 
     if (vdpau_driver_dri2) {
@@ -139,26 +143,28 @@ VdpStatus vdp_device_create_x11(
         vdpau_driver_dri2 = NULL;
     }
 
-    if (!backend_dll) {
+    if (!_vdp_driver_dll) {
         fprintf(stderr, "Failed to open VDPAU backend %s\n", dlerror());
         _VDP_ERROR_BREAKPOINT();
         return VDP_STATUS_NO_IMPLEMENTATION;
     }
 
+    _vdp_backend_dll = _vdp_driver_dll;
+
     vdpau_trace = getenv("VDPAU_TRACE");
     if (vdpau_trace && atoi(vdpau_trace)) {
-        void *         trace_dll;
         SetDllHandle * set_dll_handle;
 
-        trace_dll = dlopen(VDPAU_MODULEDIR "/libvdpau_trace.so.1", RTLD_NOW | RTLD_GLOBAL);
-        if (!trace_dll) {
+        _vdp_trace_dll = dlopen(VDPAU_MODULEDIR "/libvdpau_trace.so.1",
+                                RTLD_NOW | RTLD_GLOBAL);
+        if (!_vdp_trace_dll) {
             fprintf(stderr, "Failed to open VDPAU trace library %s\n", dlerror());
             _VDP_ERROR_BREAKPOINT();
             return VDP_STATUS_NO_IMPLEMENTATION;
         }
 
         set_dll_handle = (SetDllHandle*)dlsym(
-            trace_dll,
+            _vdp_trace_dll,
             "vdp_trace_set_backend_handle"
         );
         if (!set_dll_handle) {
@@ -167,9 +173,9 @@ VdpStatus vdp_device_create_x11(
             return VDP_STATUS_NO_IMPLEMENTATION;
         }
 
-        set_dll_handle(backend_dll);
+        set_dll_handle(_vdp_backend_dll);
 
-        backend_dll = trace_dll;
+        _vdp_backend_dll = _vdp_trace_dll;
 
         func_name = "vdp_trace_device_create_x11";
     }
@@ -177,17 +183,52 @@ VdpStatus vdp_device_create_x11(
         func_name = "vdp_imp_device_create_x11";
     }
 
-    vdp_imp_device_create_x11 = (VdpDeviceCreateX11*)dlsym(
-        backend_dll,
+    _vdp_imp_device_create_x11_proc = (VdpDeviceCreateX11*)dlsym(
+        _vdp_backend_dll,
         func_name
     );
-    if (!vdp_imp_device_create_x11) {
+    if (!_vdp_imp_device_create_x11_proc) {
         fprintf(stderr, "%s\n", dlerror());
         _VDP_ERROR_BREAKPOINT();
         return VDP_STATUS_NO_IMPLEMENTATION;
     }
 
-    return vdp_imp_device_create_x11(
+    return VDP_STATUS_OK;
+}
+
+static void _vdp_close_driver(void)
+{
+    if (_vdp_driver_dll) {
+        dlclose(_vdp_driver_dll);
+        _vdp_driver_dll = NULL;
+    }
+    if (_vdp_trace_dll) {
+        dlclose(_vdp_trace_dll);
+        _vdp_trace_dll = NULL;
+    }
+    _vdp_backend_dll = NULL;
+    _vdp_imp_device_create_x11_proc = NULL;
+}
+
+VdpStatus vdp_device_create_x11(
+    Display *             display,
+    int                   screen,
+    /* output parameters follow */
+    VdpDevice *           device,
+    VdpGetProcAddress * * get_proc_address
+)
+{
+    VdpStatus status;
+
+    if (!_vdp_imp_device_create_x11_proc) {
+        status = _vdp_open_driver(display, screen);
+        if (status != VDP_STATUS_OK) {
+            _vdp_close_driver();
+            return status;
+        }
+    }
+
+    return _vdp_imp_device_create_x11_proc(
         display,
         screen,
         device,
--
cgit v0.9.0.2-2-gbebe