~ubuntu-branches/ubuntu/precise/mesa-lts-quantal/precise-updates

« back to all changes in this revision

Viewing changes to src/glx/dri2.c

  • Committer: Package Import Robot
  • Author(s): Maarten Lankhorst
  • Date: 2012-11-30 20:58:34 UTC
  • Revision ID: package-import@ubuntu.com-20121130205834-gazuvne3fpwlf012
Tags: upstream-9.0
ImportĀ upstreamĀ versionĀ 9.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
#ifdef GLX_DIRECT_RENDERING
 
35
 
 
36
#include <stdio.h>
 
37
#include <X11/Xlibint.h>
 
38
#include <X11/extensions/Xext.h>
 
39
#include <X11/extensions/extutil.h>
 
40
#include <X11/extensions/dri2proto.h>
 
41
#include "xf86drm.h"
 
42
#include "dri2.h"
 
43
#include "glxclient.h"
 
44
#include "GL/glxext.h"
 
45
 
 
46
/* Allow the build to work with an older versions of dri2proto.h and
 
47
 * dri2tokens.h.
 
48
 */
 
49
#if DRI2_MINOR < 1
 
50
#undef DRI2_MINOR
 
51
#define DRI2_MINOR 1
 
52
#define X_DRI2GetBuffersWithFormat 7
 
53
#endif
 
54
 
 
55
 
 
56
static char dri2ExtensionName[] = DRI2_NAME;
 
57
static XExtensionInfo *dri2Info;
 
58
static XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info)
 
59
 
 
60
static Bool
 
61
DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire);
 
62
static Status
 
63
DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire);
 
64
static int
 
65
DRI2Error(Display *display, xError *err, XExtCodes *codes, int *ret_code);
 
66
 
 
67
static /* const */ XExtensionHooks dri2ExtensionHooks = {
 
68
  NULL,                   /* create_gc */
 
69
  NULL,                   /* copy_gc */
 
70
  NULL,                   /* flush_gc */
 
71
  NULL,                   /* free_gc */
 
72
  NULL,                   /* create_font */
 
73
  NULL,                   /* free_font */
 
74
  DRI2CloseDisplay,       /* close_display */
 
75
  DRI2WireToEvent,        /* wire_to_event */
 
76
  DRI2EventToWire,        /* event_to_wire */
 
77
  DRI2Error,              /* error */
 
78
  NULL,                   /* error_string */
 
79
};
 
80
 
 
81
static XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay,
 
82
                                   dri2Info,
 
83
                                   dri2ExtensionName,
 
84
                                   &dri2ExtensionHooks,
 
85
                                   0, NULL)
 
86
 
 
87
static Bool
 
88
DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire)
 
89
{
 
90
   XExtDisplayInfo *info = DRI2FindDisplay(dpy);
 
91
   struct glx_drawable *glxDraw;
 
92
 
 
93
   XextCheckExtension(dpy, info, dri2ExtensionName, False);
 
94
 
 
95
   switch ((wire->u.u.type & 0x7f) - info->codes->first_event) {
 
96
 
 
97
#ifdef X_DRI2SwapBuffers
 
98
   case DRI2_BufferSwapComplete:
 
99
   {
 
100
      GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
 
101
      xDRI2BufferSwapComplete2 *awire = (xDRI2BufferSwapComplete2 *)wire;
 
102
      __GLXDRIdrawable *pdraw;
 
103
 
 
104
      pdraw = dri2GetGlxDrawableFromXDrawableId(dpy, awire->drawable);
 
105
 
 
106
      /* Ignore swap events if we're not looking for them */
 
107
      aevent->type = dri2GetSwapEventType(dpy, awire->drawable);
 
108
      if(!aevent->type)
 
109
         return False;
 
110
 
 
111
      aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire);
 
112
      aevent->send_event = (awire->type & 0x80) != 0;
 
113
      aevent->display = dpy;
 
114
      aevent->drawable = awire->drawable;
 
115
      switch (awire->event_type) {
 
116
      case DRI2_EXCHANGE_COMPLETE:
 
117
         aevent->event_type = GLX_EXCHANGE_COMPLETE_INTEL;
 
118
         break;
 
119
      case DRI2_BLIT_COMPLETE:
 
120
         aevent->event_type = GLX_COPY_COMPLETE_INTEL;
 
121
         break;
 
122
      case DRI2_FLIP_COMPLETE:
 
123
         aevent->event_type = GLX_FLIP_COMPLETE_INTEL;
 
124
         break;
 
125
      default:
 
126
         /* unknown swap completion type */
 
127
         return False;
 
128
      }
 
129
      aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo;
 
130
      aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo;
 
131
 
 
132
      glxDraw = GetGLXDrawable(dpy, pdraw->drawable);
 
133
      if (awire->sbc < glxDraw->lastEventSbc)
 
134
         glxDraw->eventSbcWrap += 0x100000000;
 
135
      glxDraw->lastEventSbc = awire->sbc;
 
136
      aevent->sbc = awire->sbc + glxDraw->eventSbcWrap;
 
137
 
 
138
      return True;
 
139
   }
 
140
#endif
 
141
#ifdef DRI2_InvalidateBuffers
 
142
   case DRI2_InvalidateBuffers:
 
143
   {
 
144
      xDRI2InvalidateBuffers *awire = (xDRI2InvalidateBuffers *)wire;
 
145
 
 
146
      dri2InvalidateBuffers(dpy, awire->drawable);
 
147
      return False;
 
148
   }
 
149
#endif
 
150
   default:
 
151
      /* client doesn't support server event */
 
152
      break;
 
153
   }
 
154
 
 
155
   return False;
 
156
}
 
157
 
 
158
/* We don't actually support this.  It doesn't make sense for clients to
 
159
 * send each other DRI2 events.
 
160
 */
 
161
static Status
 
162
DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire)
 
163
{
 
164
   XExtDisplayInfo *info = DRI2FindDisplay(dpy);
 
165
 
 
166
   XextCheckExtension(dpy, info, dri2ExtensionName, False);
 
167
 
 
168
   switch (event->type) {
 
169
   default:
 
170
      /* client doesn't support server event */
 
171
      break;
 
172
   }
 
173
 
 
174
   return Success;
 
175
}
 
176
 
 
177
static int
 
178
DRI2Error(Display *display, xError *err, XExtCodes *codes, int *ret_code)
 
179
{
 
180
    if (err->majorCode == codes->major_opcode &&
 
181
        err->errorCode == BadDrawable &&
 
182
        err->minorCode == X_DRI2CopyRegion)
 
183
        return True;
 
184
 
 
185
    /* If the X drawable was destroyed before the GLX drawable, the
 
186
     * DRI2 drawble will be gone by the time we call
 
187
     * DRI2DestroyDrawable.  So just ignore BadDrawable here. */
 
188
    if (err->majorCode == codes->major_opcode &&
 
189
        err->errorCode == BadDrawable &&
 
190
        err->minorCode == X_DRI2DestroyDrawable)
 
191
        return True;
 
192
 
 
193
    /* If the server is non-local DRI2Connect will raise BadRequest.
 
194
     * Swallow this so that DRI2Connect can signal this in its return code */
 
195
    if (err->majorCode == codes->major_opcode &&
 
196
        err->minorCode == X_DRI2Connect &&
 
197
        err->errorCode == BadRequest) {
 
198
        *ret_code = False;
 
199
        return True;
 
200
    }
 
201
 
 
202
    return False;
 
203
}
 
204
 
 
205
Bool
 
206
DRI2QueryExtension(Display * dpy, int *eventBase, int *errorBase)
 
207
{
 
208
   XExtDisplayInfo *info = DRI2FindDisplay(dpy);
 
209
 
 
210
   if (XextHasExtension(info)) {
 
211
      *eventBase = info->codes->first_event;
 
212
      *errorBase = info->codes->first_error;
 
213
      return True;
 
214
   }
 
215
 
 
216
   return False;
 
217
}
 
218
 
 
219
Bool
 
220
DRI2QueryVersion(Display * dpy, int *major, int *minor)
 
221
{
 
222
   XExtDisplayInfo *info = DRI2FindDisplay(dpy);
 
223
   xDRI2QueryVersionReply rep;
 
224
   xDRI2QueryVersionReq *req;
 
225
   int i, nevents;
 
226
 
 
227
   XextCheckExtension(dpy, info, dri2ExtensionName, False);
 
228
 
 
229
   LockDisplay(dpy);
 
230
   GetReq(DRI2QueryVersion, req);
 
231
   req->reqType = info->codes->major_opcode;
 
232
   req->dri2ReqType = X_DRI2QueryVersion;
 
233
   req->majorVersion = DRI2_MAJOR;
 
234
   req->minorVersion = DRI2_MINOR;
 
235
   if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
 
236
      UnlockDisplay(dpy);
 
237
      SyncHandle();
 
238
      return False;
 
239
   }
 
240
   *major = rep.majorVersion;
 
241
   *minor = rep.minorVersion;
 
242
   UnlockDisplay(dpy);
 
243
   SyncHandle();
 
244
 
 
245
   switch (rep.minorVersion) {
 
246
   case 1:
 
247
           nevents = 0;
 
248
           break;
 
249
   case 2:
 
250
           nevents = 1;
 
251
           break;
 
252
   case 3:
 
253
   default:
 
254
           nevents = 2;
 
255
           break;
 
256
   }
 
257
        
 
258
   for (i = 0; i < nevents; i++) {
 
259
       XESetWireToEvent (dpy, info->codes->first_event + i, DRI2WireToEvent);
 
260
       XESetEventToWire (dpy, info->codes->first_event + i, DRI2EventToWire);
 
261
   }
 
262
 
 
263
   return True;
 
264
}
 
265
 
 
266
Bool
 
267
DRI2Connect(Display * dpy, XID window, char **driverName, char **deviceName)
 
268
{
 
269
   XExtDisplayInfo *info = DRI2FindDisplay(dpy);
 
270
   xDRI2ConnectReply rep;
 
271
   xDRI2ConnectReq *req;
 
272
   char *prime;
 
273
 
 
274
   XextCheckExtension(dpy, info, dri2ExtensionName, False);
 
275
 
 
276
   LockDisplay(dpy);
 
277
   GetReq(DRI2Connect, req);
 
278
   req->reqType = info->codes->major_opcode;
 
279
   req->dri2ReqType = X_DRI2Connect;
 
280
   req->window = window;
 
281
 
 
282
   req->driverType = DRI2DriverDRI;
 
283
#ifdef DRI2DriverPrimeShift
 
284
   prime = getenv("DRI_PRIME");
 
285
   if (prime) {
 
286
      uint32_t primeid;
 
287
      errno = 0;
 
288
      primeid = strtoul(prime, NULL, 0);
 
289
      if (errno == 0)
 
290
         req->driverType |= ((primeid & DRI2DriverPrimeMask) << DRI2DriverPrimeShift);
 
291
   }
 
292
#endif
 
293
 
 
294
   if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
 
295
      UnlockDisplay(dpy);
 
296
      SyncHandle();
 
297
      return False;
 
298
   }
 
299
 
 
300
   if (rep.driverNameLength == 0 && rep.deviceNameLength == 0) {
 
301
      UnlockDisplay(dpy);
 
302
      SyncHandle();
 
303
      return False;
 
304
   }
 
305
 
 
306
   *driverName = Xmalloc(rep.driverNameLength + 1);
 
307
   if (*driverName == NULL) {
 
308
      _XEatData(dpy,
 
309
                ((rep.driverNameLength + 3) & ~3) +
 
310
                ((rep.deviceNameLength + 3) & ~3));
 
311
      UnlockDisplay(dpy);
 
312
      SyncHandle();
 
313
      return False;
 
314
   }
 
315
   _XReadPad(dpy, *driverName, rep.driverNameLength);
 
316
   (*driverName)[rep.driverNameLength] = '\0';
 
317
 
 
318
   *deviceName = Xmalloc(rep.deviceNameLength + 1);
 
319
   if (*deviceName == NULL) {
 
320
      Xfree(*driverName);
 
321
      _XEatData(dpy, ((rep.deviceNameLength + 3) & ~3));
 
322
      UnlockDisplay(dpy);
 
323
      SyncHandle();
 
324
      return False;
 
325
   }
 
326
   _XReadPad(dpy, *deviceName, rep.deviceNameLength);
 
327
   (*deviceName)[rep.deviceNameLength] = '\0';
 
328
 
 
329
   UnlockDisplay(dpy);
 
330
   SyncHandle();
 
331
 
 
332
   return True;
 
333
}
 
334
 
 
335
Bool
 
336
DRI2Authenticate(Display * dpy, XID window, drm_magic_t magic)
 
337
{
 
338
   XExtDisplayInfo *info = DRI2FindDisplay(dpy);
 
339
   xDRI2AuthenticateReq *req;
 
340
   xDRI2AuthenticateReply rep;
 
341
 
 
342
   XextCheckExtension(dpy, info, dri2ExtensionName, False);
 
343
 
 
344
   LockDisplay(dpy);
 
345
   GetReq(DRI2Authenticate, req);
 
346
   req->reqType = info->codes->major_opcode;
 
347
   req->dri2ReqType = X_DRI2Authenticate;
 
348
   req->window = window;
 
349
   req->magic = magic;
 
350
 
 
351
   if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
 
352
      UnlockDisplay(dpy);
 
353
      SyncHandle();
 
354
      return False;
 
355
   }
 
356
 
 
357
   UnlockDisplay(dpy);
 
358
   SyncHandle();
 
359
 
 
360
   return rep.authenticated;
 
361
}
 
362
 
 
363
void
 
364
DRI2CreateDrawable(Display * dpy, XID drawable)
 
365
{
 
366
   XExtDisplayInfo *info = DRI2FindDisplay(dpy);
 
367
   xDRI2CreateDrawableReq *req;
 
368
 
 
369
   XextSimpleCheckExtension(dpy, info, dri2ExtensionName);
 
370
 
 
371
   LockDisplay(dpy);
 
372
   GetReq(DRI2CreateDrawable, req);
 
373
   req->reqType = info->codes->major_opcode;
 
374
   req->dri2ReqType = X_DRI2CreateDrawable;
 
375
   req->drawable = drawable;
 
376
   UnlockDisplay(dpy);
 
377
   SyncHandle();
 
378
}
 
379
 
 
380
void
 
381
DRI2DestroyDrawable(Display * dpy, XID drawable)
 
382
{
 
383
   XExtDisplayInfo *info = DRI2FindDisplay(dpy);
 
384
   xDRI2DestroyDrawableReq *req;
 
385
 
 
386
   XextSimpleCheckExtension(dpy, info, dri2ExtensionName);
 
387
 
 
388
   XSync(dpy, False);
 
389
 
 
390
   LockDisplay(dpy);
 
391
   GetReq(DRI2DestroyDrawable, req);
 
392
   req->reqType = info->codes->major_opcode;
 
393
   req->dri2ReqType = X_DRI2DestroyDrawable;
 
394
   req->drawable = drawable;
 
395
   UnlockDisplay(dpy);
 
396
   SyncHandle();
 
397
}
 
398
 
 
399
DRI2Buffer *
 
400
DRI2GetBuffers(Display * dpy, XID drawable,
 
401
               int *width, int *height,
 
402
               unsigned int *attachments, int count, int *outCount)
 
403
{
 
404
   XExtDisplayInfo *info = DRI2FindDisplay(dpy);
 
405
   xDRI2GetBuffersReply rep;
 
406
   xDRI2GetBuffersReq *req;
 
407
   DRI2Buffer *buffers;
 
408
   xDRI2Buffer repBuffer;
 
409
   CARD32 *p;
 
410
   int i;
 
411
 
 
412
   XextCheckExtension(dpy, info, dri2ExtensionName, False);
 
413
 
 
414
   LockDisplay(dpy);
 
415
   GetReqExtra(DRI2GetBuffers, count * 4, req);
 
416
   req->reqType = info->codes->major_opcode;
 
417
   req->dri2ReqType = X_DRI2GetBuffers;
 
418
   req->drawable = drawable;
 
419
   req->count = count;
 
420
   p = (CARD32 *) & req[1];
 
421
   for (i = 0; i < count; i++)
 
422
      p[i] = attachments[i];
 
423
 
 
424
   if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
 
425
      UnlockDisplay(dpy);
 
426
      SyncHandle();
 
427
      return NULL;
 
428
   }
 
429
 
 
430
   *width = rep.width;
 
431
   *height = rep.height;
 
432
   *outCount = rep.count;
 
433
 
 
434
   buffers = Xmalloc(rep.count * sizeof buffers[0]);
 
435
   if (buffers == NULL) {
 
436
      _XEatData(dpy, rep.count * sizeof repBuffer);
 
437
      UnlockDisplay(dpy);
 
438
      SyncHandle();
 
439
      return NULL;
 
440
   }
 
441
 
 
442
   for (i = 0; i < rep.count; i++) {
 
443
      _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer);
 
444
      buffers[i].attachment = repBuffer.attachment;
 
445
      buffers[i].name = repBuffer.name;
 
446
      buffers[i].pitch = repBuffer.pitch;
 
447
      buffers[i].cpp = repBuffer.cpp;
 
448
      buffers[i].flags = repBuffer.flags;
 
449
   }
 
450
 
 
451
   UnlockDisplay(dpy);
 
452
   SyncHandle();
 
453
 
 
454
   return buffers;
 
455
}
 
456
 
 
457
 
 
458
DRI2Buffer *
 
459
DRI2GetBuffersWithFormat(Display * dpy, XID drawable,
 
460
                         int *width, int *height,
 
461
                         unsigned int *attachments, int count, int *outCount)
 
462
{
 
463
   XExtDisplayInfo *info = DRI2FindDisplay(dpy);
 
464
   xDRI2GetBuffersReply rep;
 
465
   xDRI2GetBuffersReq *req;
 
466
   DRI2Buffer *buffers;
 
467
   xDRI2Buffer repBuffer;
 
468
   CARD32 *p;
 
469
   int i;
 
470
 
 
471
   XextCheckExtension(dpy, info, dri2ExtensionName, False);
 
472
 
 
473
   LockDisplay(dpy);
 
474
   GetReqExtra(DRI2GetBuffers, count * (4 * 2), req);
 
475
   req->reqType = info->codes->major_opcode;
 
476
   req->dri2ReqType = X_DRI2GetBuffersWithFormat;
 
477
   req->drawable = drawable;
 
478
   req->count = count;
 
479
   p = (CARD32 *) & req[1];
 
480
   for (i = 0; i < (count * 2); i++)
 
481
      p[i] = attachments[i];
 
482
 
 
483
   if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
 
484
      UnlockDisplay(dpy);
 
485
      SyncHandle();
 
486
      return NULL;
 
487
   }
 
488
 
 
489
   *width = rep.width;
 
490
   *height = rep.height;
 
491
   *outCount = rep.count;
 
492
 
 
493
   buffers = Xmalloc(rep.count * sizeof buffers[0]);
 
494
   if (buffers == NULL) {
 
495
      _XEatData(dpy, rep.count * sizeof repBuffer);
 
496
      UnlockDisplay(dpy);
 
497
      SyncHandle();
 
498
      return NULL;
 
499
   }
 
500
 
 
501
   for (i = 0; i < rep.count; i++) {
 
502
      _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer);
 
503
      buffers[i].attachment = repBuffer.attachment;
 
504
      buffers[i].name = repBuffer.name;
 
505
      buffers[i].pitch = repBuffer.pitch;
 
506
      buffers[i].cpp = repBuffer.cpp;
 
507
      buffers[i].flags = repBuffer.flags;
 
508
   }
 
509
 
 
510
   UnlockDisplay(dpy);
 
511
   SyncHandle();
 
512
 
 
513
   return buffers;
 
514
}
 
515
 
 
516
 
 
517
void
 
518
DRI2CopyRegion(Display * dpy, XID drawable, XserverRegion region,
 
519
               CARD32 dest, CARD32 src)
 
520
{
 
521
   XExtDisplayInfo *info = DRI2FindDisplay(dpy);
 
522
   xDRI2CopyRegionReq *req;
 
523
   xDRI2CopyRegionReply rep;
 
524
 
 
525
   XextSimpleCheckExtension(dpy, info, dri2ExtensionName);
 
526
 
 
527
   LockDisplay(dpy);
 
528
   GetReq(DRI2CopyRegion, req);
 
529
   req->reqType = info->codes->major_opcode;
 
530
   req->dri2ReqType = X_DRI2CopyRegion;
 
531
   req->drawable = drawable;
 
532
   req->region = region;
 
533
   req->dest = dest;
 
534
   req->src = src;
 
535
 
 
536
   _XReply(dpy, (xReply *) & rep, 0, xFalse);
 
537
 
 
538
   UnlockDisplay(dpy);
 
539
   SyncHandle();
 
540
}
 
541
 
 
542
#ifdef X_DRI2SwapBuffers
 
543
static void
 
544
load_swap_req(xDRI2SwapBuffersReq *req, CARD64 target, CARD64 divisor,
 
545
             CARD64 remainder)
 
546
{
 
547
    req->target_msc_hi = target >> 32;
 
548
    req->target_msc_lo = target & 0xffffffff;
 
549
    req->divisor_hi = divisor >> 32;
 
550
    req->divisor_lo = divisor & 0xffffffff;
 
551
    req->remainder_hi = remainder >> 32;
 
552
    req->remainder_lo = remainder & 0xffffffff;
 
553
}
 
554
 
 
555
static CARD64
 
556
vals_to_card64(CARD32 lo, CARD32 hi)
 
557
{
 
558
    return (CARD64)hi << 32 | lo;
 
559
}
 
560
 
 
561
void DRI2SwapBuffers(Display *dpy, XID drawable, CARD64 target_msc,
 
562
                     CARD64 divisor, CARD64 remainder, CARD64 *count)
 
563
{
 
564
    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
 
565
    xDRI2SwapBuffersReq *req;
 
566
    xDRI2SwapBuffersReply rep;
 
567
 
 
568
    XextSimpleCheckExtension (dpy, info, dri2ExtensionName);
 
569
 
 
570
    LockDisplay(dpy);
 
571
    GetReq(DRI2SwapBuffers, req);
 
572
    req->reqType = info->codes->major_opcode;
 
573
    req->dri2ReqType = X_DRI2SwapBuffers;
 
574
    req->drawable = drawable;
 
575
    load_swap_req(req, target_msc, divisor, remainder);
 
576
 
 
577
    _XReply(dpy, (xReply *)&rep, 0, xFalse);
 
578
 
 
579
    *count = vals_to_card64(rep.swap_lo, rep.swap_hi);
 
580
 
 
581
    UnlockDisplay(dpy);
 
582
    SyncHandle();
 
583
}
 
584
#endif
 
585
 
 
586
#ifdef X_DRI2GetMSC
 
587
Bool DRI2GetMSC(Display *dpy, XID drawable, CARD64 *ust, CARD64 *msc,
 
588
                CARD64 *sbc)
 
589
{
 
590
    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
 
591
    xDRI2GetMSCReq *req;
 
592
    xDRI2MSCReply rep;
 
593
 
 
594
    XextCheckExtension (dpy, info, dri2ExtensionName, False);
 
595
 
 
596
    LockDisplay(dpy);
 
597
    GetReq(DRI2GetMSC, req);
 
598
    req->reqType = info->codes->major_opcode;
 
599
    req->dri2ReqType = X_DRI2GetMSC;
 
600
    req->drawable = drawable;
 
601
 
 
602
    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
 
603
        UnlockDisplay(dpy);
 
604
        SyncHandle();
 
605
        return False;
 
606
    }
 
607
 
 
608
    *ust = vals_to_card64(rep.ust_lo, rep.ust_hi);
 
609
    *msc = vals_to_card64(rep.msc_lo, rep.msc_hi);
 
610
    *sbc = vals_to_card64(rep.sbc_lo, rep.sbc_hi);
 
611
 
 
612
    UnlockDisplay(dpy);
 
613
    SyncHandle();
 
614
 
 
615
    return True;
 
616
}
 
617
#endif
 
618
 
 
619
#ifdef X_DRI2WaitMSC
 
620
static void
 
621
load_msc_req(xDRI2WaitMSCReq *req, CARD64 target, CARD64 divisor,
 
622
             CARD64 remainder)
 
623
{
 
624
    req->target_msc_hi = target >> 32;
 
625
    req->target_msc_lo = target & 0xffffffff;
 
626
    req->divisor_hi = divisor >> 32;
 
627
    req->divisor_lo = divisor & 0xffffffff;
 
628
    req->remainder_hi = remainder >> 32;
 
629
    req->remainder_lo = remainder & 0xffffffff;
 
630
}
 
631
 
 
632
Bool DRI2WaitMSC(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor,
 
633
                 CARD64 remainder, CARD64 *ust, CARD64 *msc, CARD64 *sbc)
 
634
{
 
635
    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
 
636
    xDRI2WaitMSCReq *req;
 
637
    xDRI2MSCReply rep;
 
638
 
 
639
    XextCheckExtension (dpy, info, dri2ExtensionName, False);
 
640
 
 
641
    LockDisplay(dpy);
 
642
    GetReq(DRI2WaitMSC, req);
 
643
    req->reqType = info->codes->major_opcode;
 
644
    req->dri2ReqType = X_DRI2WaitMSC;
 
645
    req->drawable = drawable;
 
646
    load_msc_req(req, target_msc, divisor, remainder);
 
647
 
 
648
    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
 
649
        UnlockDisplay(dpy);
 
650
        SyncHandle();
 
651
        return False;
 
652
    }
 
653
 
 
654
    *ust = ((CARD64)rep.ust_hi << 32) | (CARD64)rep.ust_lo;
 
655
    *msc = ((CARD64)rep.msc_hi << 32) | (CARD64)rep.msc_lo;
 
656
    *sbc = ((CARD64)rep.sbc_hi << 32) | (CARD64)rep.sbc_lo;
 
657
 
 
658
    UnlockDisplay(dpy);
 
659
    SyncHandle();
 
660
 
 
661
    return True;
 
662
}
 
663
#endif
 
664
 
 
665
#ifdef X_DRI2WaitSBC
 
666
static void
 
667
load_sbc_req(xDRI2WaitSBCReq *req, CARD64 target)
 
668
{
 
669
    req->target_sbc_hi = target >> 32;
 
670
    req->target_sbc_lo = target & 0xffffffff;
 
671
}
 
672
 
 
673
Bool DRI2WaitSBC(Display *dpy, XID drawable, CARD64 target_sbc, CARD64 *ust,
 
674
                 CARD64 *msc, CARD64 *sbc)
 
675
{
 
676
    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
 
677
    xDRI2WaitSBCReq *req;
 
678
    xDRI2MSCReply rep;
 
679
 
 
680
    XextCheckExtension (dpy, info, dri2ExtensionName, False);
 
681
 
 
682
    LockDisplay(dpy);
 
683
    GetReq(DRI2WaitSBC, req);
 
684
    req->reqType = info->codes->major_opcode;
 
685
    req->dri2ReqType = X_DRI2WaitSBC;
 
686
    req->drawable = drawable;
 
687
    load_sbc_req(req, target_sbc);
 
688
 
 
689
    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
 
690
        UnlockDisplay(dpy);
 
691
        SyncHandle();
 
692
        return False;
 
693
    }
 
694
 
 
695
    *ust = ((CARD64)rep.ust_hi << 32) | rep.ust_lo;
 
696
    *msc = ((CARD64)rep.msc_hi << 32) | rep.msc_lo;
 
697
    *sbc = ((CARD64)rep.sbc_hi << 32) | rep.sbc_lo;
 
698
 
 
699
    UnlockDisplay(dpy);
 
700
    SyncHandle();
 
701
 
 
702
    return True;
 
703
}
 
704
#endif
 
705
 
 
706
#ifdef X_DRI2SwapInterval
 
707
void DRI2SwapInterval(Display *dpy, XID drawable, int interval)
 
708
{
 
709
    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
 
710
    xDRI2SwapIntervalReq *req;
 
711
 
 
712
    XextSimpleCheckExtension (dpy, info, dri2ExtensionName);
 
713
 
 
714
    LockDisplay(dpy);
 
715
    GetReq(DRI2SwapInterval, req);
 
716
    req->reqType = info->codes->major_opcode;
 
717
    req->dri2ReqType = X_DRI2SwapInterval;
 
718
    req->drawable = drawable;
 
719
    req->interval = interval;
 
720
    UnlockDisplay(dpy);
 
721
    SyncHandle();
 
722
}
 
723
#endif
 
724
 
 
725
#endif /* GLX_DIRECT_RENDERING */