Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5362 | serge | 1 | /* |
2 | * Copyright © 2008 Red Hat, Inc. |
||
3 | * |
||
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
||
5 | * copy of this software and associated documentation files (the "Soft- |
||
6 | * ware"), to deal in the Software without restriction, including without |
||
7 | * limitation the rights to use, copy, modify, merge, publish, distribute, |
||
8 | * and/or sell copies of the Software, and to permit persons to whom the |
||
9 | * Software is furnished to do so, provided that the above copyright |
||
10 | * notice(s) and this permission notice appear in all copies of the Soft- |
||
11 | * ware and that both the above copyright notice(s) and this permission |
||
12 | * notice appear in supporting documentation. |
||
13 | * |
||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
||
15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- |
||
16 | * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY |
||
17 | * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN |
||
18 | * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- |
||
19 | * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, |
||
20 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
||
21 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- |
||
22 | * MANCE OF THIS SOFTWARE. |
||
23 | * |
||
24 | * Except as contained in this notice, the name of a copyright holder shall |
||
25 | * not be used in advertising or otherwise to promote the sale, use or |
||
26 | * other dealings in this Software without prior written authorization of |
||
27 | * the copyright holder. |
||
28 | * |
||
29 | * Authors: |
||
30 | * Kristian Høgsberg (krh@redhat.com) |
||
31 | */ |
||
32 | |||
33 | |||
34 | #define NEED_REPLIES |
||
35 | #include |
||
36 | #include |
||
37 | #include |
||
38 | #include "xf86drm.h" |
||
39 | #include "va_dri2.h" |
||
40 | #include "va_dri2str.h" |
||
41 | #include "va_dri2tokens.h" |
||
42 | |||
43 | #ifndef DRI2DriverDRI |
||
44 | #define DRI2DriverDRI 0 |
||
45 | #endif |
||
46 | |||
47 | static int |
||
48 | VA_DRI2Error(Display *dpy, xError *err, XExtCodes *codes, int *ret_code); |
||
49 | |||
50 | static char va_dri2ExtensionName[] = DRI2_NAME; |
||
51 | static XExtensionInfo _va_dri2_info_data; |
||
52 | static XExtensionInfo *va_dri2Info = &_va_dri2_info_data; |
||
53 | static XEXT_GENERATE_CLOSE_DISPLAY (VA_DRI2CloseDisplay, va_dri2Info) |
||
54 | static /* const */ XExtensionHooks va_dri2ExtensionHooks = { |
||
55 | NULL, /* create_gc */ |
||
56 | NULL, /* copy_gc */ |
||
57 | NULL, /* flush_gc */ |
||
58 | NULL, /* free_gc */ |
||
59 | NULL, /* create_font */ |
||
60 | NULL, /* free_font */ |
||
61 | VA_DRI2CloseDisplay, /* close_display */ |
||
62 | NULL, /* wire_to_event */ |
||
63 | NULL, /* event_to_wire */ |
||
64 | VA_DRI2Error, /* error */ |
||
65 | NULL, /* error_string */ |
||
66 | }; |
||
67 | |||
68 | static XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay, va_dri2Info, |
||
69 | va_dri2ExtensionName, |
||
70 | &va_dri2ExtensionHooks, |
||
71 | 0, NULL) |
||
72 | |||
73 | static int |
||
74 | VA_DRI2Error(Display *dpy, xError *err, XExtCodes *codes, int *ret_code) |
||
75 | { |
||
76 | /* |
||
77 | * If the X drawable was destroyed before the VA drawable, the DRI2 drawable |
||
78 | * will be gone by the time we call VA_DRI2DestroyDrawable(). So, simply |
||
79 | * ignore BadDrawable errors in that case. |
||
80 | */ |
||
81 | if (err->majorCode == codes->major_opcode && |
||
82 | err->errorCode == BadDrawable && |
||
83 | err->minorCode == X_DRI2DestroyDrawable) |
||
84 | return True; |
||
85 | |||
86 | return False; |
||
87 | } |
||
88 | |||
89 | Bool VA_DRI2QueryExtension(Display *dpy, int *eventBase, int *errorBase) |
||
90 | { |
||
91 | XExtDisplayInfo *info = DRI2FindDisplay(dpy); |
||
92 | |||
93 | if (XextHasExtension(info)) { |
||
94 | *eventBase = info->codes->first_event; |
||
95 | *errorBase = info->codes->first_error; |
||
96 | return True; |
||
97 | } |
||
98 | |||
99 | return False; |
||
100 | } |
||
101 | |||
102 | Bool VA_DRI2QueryVersion(Display *dpy, int *major, int *minor) |
||
103 | { |
||
104 | XExtDisplayInfo *info = DRI2FindDisplay (dpy); |
||
105 | xDRI2QueryVersionReply rep; |
||
106 | xDRI2QueryVersionReq *req; |
||
107 | |||
108 | XextCheckExtension (dpy, info, va_dri2ExtensionName, False); |
||
109 | |||
110 | LockDisplay(dpy); |
||
111 | GetReq(DRI2QueryVersion, req); |
||
112 | req->reqType = info->codes->major_opcode; |
||
113 | req->dri2ReqType = X_DRI2QueryVersion; |
||
114 | req->majorVersion = DRI2_MAJOR; |
||
115 | req->minorVersion = DRI2_MINOR; |
||
116 | if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { |
||
117 | UnlockDisplay(dpy); |
||
118 | SyncHandle(); |
||
119 | return False; |
||
120 | } |
||
121 | *major = rep.majorVersion; |
||
122 | *minor = rep.minorVersion; |
||
123 | UnlockDisplay(dpy); |
||
124 | SyncHandle(); |
||
125 | |||
126 | return True; |
||
127 | } |
||
128 | |||
129 | Bool VA_DRI2Connect(Display *dpy, XID window, |
||
130 | char **driverName, char **deviceName) |
||
131 | { |
||
132 | XExtDisplayInfo *info = DRI2FindDisplay(dpy); |
||
133 | xDRI2ConnectReply rep; |
||
134 | xDRI2ConnectReq *req; |
||
135 | |||
136 | XextCheckExtension (dpy, info, va_dri2ExtensionName, False); |
||
137 | |||
138 | LockDisplay(dpy); |
||
139 | GetReq(DRI2Connect, req); |
||
140 | req->reqType = info->codes->major_opcode; |
||
141 | req->dri2ReqType = X_DRI2Connect; |
||
142 | req->window = window; |
||
143 | req->driverType = DRI2DriverDRI; |
||
144 | if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { |
||
145 | UnlockDisplay(dpy); |
||
146 | SyncHandle(); |
||
147 | return False; |
||
148 | } |
||
149 | |||
150 | if (rep.driverNameLength == 0 && rep.deviceNameLength == 0) { |
||
151 | UnlockDisplay(dpy); |
||
152 | SyncHandle(); |
||
153 | return False; |
||
154 | } |
||
155 | |||
156 | *driverName = Xmalloc(rep.driverNameLength + 1); |
||
157 | if (*driverName == NULL) { |
||
158 | _XEatData(dpy, |
||
159 | ((rep.driverNameLength + 3) & ~3) + |
||
160 | ((rep.deviceNameLength + 3) & ~3)); |
||
161 | UnlockDisplay(dpy); |
||
162 | SyncHandle(); |
||
163 | return False; |
||
164 | } |
||
165 | _XReadPad(dpy, *driverName, rep.driverNameLength); |
||
166 | (*driverName)[rep.driverNameLength] = '\0'; |
||
167 | |||
168 | *deviceName = Xmalloc(rep.deviceNameLength + 1); |
||
169 | if (*deviceName == NULL) { |
||
170 | Xfree(*driverName); |
||
171 | _XEatData(dpy, ((rep.deviceNameLength + 3) & ~3)); |
||
172 | UnlockDisplay(dpy); |
||
173 | SyncHandle(); |
||
174 | return False; |
||
175 | } |
||
176 | _XReadPad(dpy, *deviceName, rep.deviceNameLength); |
||
177 | (*deviceName)[rep.deviceNameLength] = '\0'; |
||
178 | |||
179 | UnlockDisplay(dpy); |
||
180 | SyncHandle(); |
||
181 | |||
182 | return True; |
||
183 | } |
||
184 | |||
185 | Bool VA_DRI2Authenticate(Display *dpy, XID window, drm_magic_t magic) |
||
186 | { |
||
187 | XExtDisplayInfo *info = DRI2FindDisplay(dpy); |
||
188 | xDRI2AuthenticateReq *req; |
||
189 | xDRI2AuthenticateReply rep; |
||
190 | |||
191 | XextCheckExtension (dpy, info, va_dri2ExtensionName, False); |
||
192 | |||
193 | LockDisplay(dpy); |
||
194 | GetReq(DRI2Authenticate, req); |
||
195 | req->reqType = info->codes->major_opcode; |
||
196 | req->dri2ReqType = X_DRI2Authenticate; |
||
197 | req->window = window; |
||
198 | req->magic = magic; |
||
199 | |||
200 | if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { |
||
201 | UnlockDisplay(dpy); |
||
202 | SyncHandle(); |
||
203 | return False; |
||
204 | } |
||
205 | |||
206 | UnlockDisplay(dpy); |
||
207 | SyncHandle(); |
||
208 | |||
209 | return rep.authenticated; |
||
210 | } |
||
211 | |||
212 | void VA_DRI2CreateDrawable(Display *dpy, XID drawable) |
||
213 | { |
||
214 | XExtDisplayInfo *info = DRI2FindDisplay(dpy); |
||
215 | xDRI2CreateDrawableReq *req; |
||
216 | |||
217 | XextSimpleCheckExtension (dpy, info, va_dri2ExtensionName); |
||
218 | |||
219 | LockDisplay(dpy); |
||
220 | GetReq(DRI2CreateDrawable, req); |
||
221 | req->reqType = info->codes->major_opcode; |
||
222 | req->dri2ReqType = X_DRI2CreateDrawable; |
||
223 | req->drawable = drawable; |
||
224 | UnlockDisplay(dpy); |
||
225 | SyncHandle(); |
||
226 | } |
||
227 | |||
228 | void VA_DRI2DestroyDrawable(Display *dpy, XID drawable) |
||
229 | { |
||
230 | XExtDisplayInfo *info = DRI2FindDisplay(dpy); |
||
231 | xDRI2DestroyDrawableReq *req; |
||
232 | |||
233 | XextSimpleCheckExtension (dpy, info, va_dri2ExtensionName); |
||
234 | |||
235 | XSync(dpy, False); |
||
236 | |||
237 | LockDisplay(dpy); |
||
238 | GetReq(DRI2DestroyDrawable, req); |
||
239 | req->reqType = info->codes->major_opcode; |
||
240 | req->dri2ReqType = X_DRI2DestroyDrawable; |
||
241 | req->drawable = drawable; |
||
242 | UnlockDisplay(dpy); |
||
243 | SyncHandle(); |
||
244 | } |
||
245 | |||
246 | VA_DRI2Buffer *VA_DRI2GetBuffers(Display *dpy, XID drawable, |
||
247 | int *width, int *height, |
||
248 | unsigned int *attachments, int count, |
||
249 | int *outCount) |
||
250 | { |
||
251 | XExtDisplayInfo *info = DRI2FindDisplay(dpy); |
||
252 | xDRI2GetBuffersReply rep; |
||
253 | xDRI2GetBuffersReq *req; |
||
254 | VA_DRI2Buffer *buffers; |
||
255 | xDRI2Buffer repBuffer; |
||
256 | CARD32 *p; |
||
257 | int i; |
||
258 | |||
259 | XextCheckExtension (dpy, info, va_dri2ExtensionName, False); |
||
260 | |||
261 | LockDisplay(dpy); |
||
262 | GetReqExtra(DRI2GetBuffers, count * 4, req); |
||
263 | req->reqType = info->codes->major_opcode; |
||
264 | req->dri2ReqType = X_DRI2GetBuffers; |
||
265 | req->drawable = drawable; |
||
266 | req->count = count; |
||
267 | p = (CARD32 *) &req[1]; |
||
268 | for (i = 0; i < count; i++) |
||
269 | p[i] = attachments[i]; |
||
270 | |||
271 | if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { |
||
272 | UnlockDisplay(dpy); |
||
273 | SyncHandle(); |
||
274 | return NULL; |
||
275 | } |
||
276 | |||
277 | *width = rep.width; |
||
278 | *height = rep.height; |
||
279 | *outCount = rep.count; |
||
280 | |||
281 | buffers = Xmalloc(rep.count * sizeof buffers[0]); |
||
282 | if (buffers == NULL) { |
||
283 | _XEatData(dpy, rep.count * sizeof repBuffer); |
||
284 | UnlockDisplay(dpy); |
||
285 | SyncHandle(); |
||
286 | return NULL; |
||
287 | } |
||
288 | |||
289 | for (i = 0; i < rep.count; i++) { |
||
290 | _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer); |
||
291 | buffers[i].attachment = repBuffer.attachment; |
||
292 | buffers[i].name = repBuffer.name; |
||
293 | buffers[i].pitch = repBuffer.pitch; |
||
294 | buffers[i].cpp = repBuffer.cpp; |
||
295 | buffers[i].flags = repBuffer.flags; |
||
296 | } |
||
297 | |||
298 | UnlockDisplay(dpy); |
||
299 | SyncHandle(); |
||
300 | |||
301 | return buffers; |
||
302 | } |
||
303 | |||
304 | void VA_DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region, |
||
305 | CARD32 dest, CARD32 src) |
||
306 | { |
||
307 | XExtDisplayInfo *info = DRI2FindDisplay(dpy); |
||
308 | xDRI2CopyRegionReq *req; |
||
309 | xDRI2CopyRegionReply rep; |
||
310 | |||
311 | XextSimpleCheckExtension (dpy, info, va_dri2ExtensionName); |
||
312 | |||
313 | LockDisplay(dpy); |
||
314 | GetReq(DRI2CopyRegion, req); |
||
315 | req->reqType = info->codes->major_opcode; |
||
316 | req->dri2ReqType = X_DRI2CopyRegion; |
||
317 | req->drawable = drawable; |
||
318 | req->region = region; |
||
319 | req->dest = dest; |
||
320 | req->src = src; |
||
321 | |||
322 | _XReply(dpy, (xReply *)&rep, 0, xFalse); |
||
323 | |||
324 | UnlockDisplay(dpy); |
||
325 | SyncHandle(); |
||
326 | } |
||
327 | |||
328 | static void |
||
329 | load_swap_req(xDRI2SwapBuffersReq *req, CARD64 target, CARD64 divisor, |
||
330 | CARD64 remainder) |
||
331 | { |
||
332 | req->target_msc_hi = target >> 32; |
||
333 | req->target_msc_lo = target & 0xffffffff; |
||
334 | req->divisor_hi = divisor >> 32; |
||
335 | req->divisor_lo = divisor & 0xffffffff; |
||
336 | req->remainder_hi = remainder >> 32; |
||
337 | req->remainder_lo = remainder & 0xffffffff; |
||
338 | } |
||
339 | |||
340 | static CARD64 |
||
341 | vals_to_card64(CARD32 lo, CARD32 hi) |
||
342 | { |
||
343 | return (CARD64)hi << 32 | lo; |
||
344 | } |
||
345 | |||
346 | void VA_DRI2SwapBuffers(Display *dpy, XID drawable, CARD64 target_msc, |
||
347 | CARD64 divisor, CARD64 remainder, CARD64 *count) |
||
348 | { |
||
349 | XExtDisplayInfo *info = DRI2FindDisplay(dpy); |
||
350 | xDRI2SwapBuffersReq *req; |
||
351 | xDRI2SwapBuffersReply rep; |
||
352 | |||
353 | XextSimpleCheckExtension (dpy, info, va_dri2ExtensionName); |
||
354 | |||
355 | LockDisplay(dpy); |
||
356 | GetReq(DRI2SwapBuffers, req); |
||
357 | req->reqType = info->codes->major_opcode; |
||
358 | req->dri2ReqType = X_DRI2SwapBuffers; |
||
359 | req->drawable = drawable; |
||
360 | load_swap_req(req, target_msc, divisor, remainder); |
||
361 | |||
362 | _XReply(dpy, (xReply *)&rep, 0, xFalse); |
||
363 | |||
364 | *count = vals_to_card64(rep.swap_lo, rep.swap_hi); |
||
365 | |||
366 | UnlockDisplay(dpy); |
||
367 | SyncHandle(); |
||
368 | }><>>> |