xref: /aosp_15_r20/external/mesa3d/src/glx/dri2.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2008 Red Hat, Inc.
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Soft-
6*61046927SAndroid Build Coastguard Worker  * ware"), to deal in the Software without restriction, including without
7*61046927SAndroid Build Coastguard Worker  * limitation the rights to use, copy, modify, merge, publish, distribute,
8*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, provided that the above copyright
10*61046927SAndroid Build Coastguard Worker  * notice(s) and this permission notice appear in all copies of the Soft-
11*61046927SAndroid Build Coastguard Worker  * ware and that both the above copyright notice(s) and this permission
12*61046927SAndroid Build Coastguard Worker  * notice appear in supporting documentation.
13*61046927SAndroid Build Coastguard Worker  *
14*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15*61046927SAndroid Build Coastguard Worker  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
16*61046927SAndroid Build Coastguard Worker  * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
17*61046927SAndroid Build Coastguard Worker  * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
18*61046927SAndroid Build Coastguard Worker  * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
19*61046927SAndroid Build Coastguard Worker  * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20*61046927SAndroid Build Coastguard Worker  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21*61046927SAndroid Build Coastguard Worker  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
22*61046927SAndroid Build Coastguard Worker  * MANCE OF THIS SOFTWARE.
23*61046927SAndroid Build Coastguard Worker  *
24*61046927SAndroid Build Coastguard Worker  * Except as contained in this notice, the name of a copyright holder shall
25*61046927SAndroid Build Coastguard Worker  * not be used in advertising or otherwise to promote the sale, use or
26*61046927SAndroid Build Coastguard Worker  * other dealings in this Software without prior written authorization of
27*61046927SAndroid Build Coastguard Worker  * the copyright holder.
28*61046927SAndroid Build Coastguard Worker  *
29*61046927SAndroid Build Coastguard Worker  * Authors:
30*61046927SAndroid Build Coastguard Worker  *   Kristian Høgsberg ([email protected])
31*61046927SAndroid Build Coastguard Worker  */
32*61046927SAndroid Build Coastguard Worker 
33*61046927SAndroid Build Coastguard Worker 
34*61046927SAndroid Build Coastguard Worker #if defined(GLX_DIRECT_RENDERING) && (!defined(GLX_USE_APPLEGL) || defined(GLX_USE_APPLE))
35*61046927SAndroid Build Coastguard Worker 
36*61046927SAndroid Build Coastguard Worker #include <stdio.h>
37*61046927SAndroid Build Coastguard Worker #include <X11/Xlibint.h>
38*61046927SAndroid Build Coastguard Worker #include <X11/extensions/Xext.h>
39*61046927SAndroid Build Coastguard Worker #include <X11/extensions/extutil.h>
40*61046927SAndroid Build Coastguard Worker #include <X11/extensions/dri2proto.h>
41*61046927SAndroid Build Coastguard Worker #include "dri2.h"
42*61046927SAndroid Build Coastguard Worker #include "glxclient.h"
43*61046927SAndroid Build Coastguard Worker #include "GL/glxext.h"
44*61046927SAndroid Build Coastguard Worker 
45*61046927SAndroid Build Coastguard Worker #if defined(__APPLE__) || defined(__MACOSX)
46*61046927SAndroid Build Coastguard Worker #include "apple/appledri.h"
47*61046927SAndroid Build Coastguard Worker #include "apple/appledristr.h"
48*61046927SAndroid Build Coastguard Worker #endif
49*61046927SAndroid Build Coastguard Worker 
50*61046927SAndroid Build Coastguard Worker /* Allow the build to work with an older versions of dri2proto.h and
51*61046927SAndroid Build Coastguard Worker  * dri2tokens.h.
52*61046927SAndroid Build Coastguard Worker  */
53*61046927SAndroid Build Coastguard Worker #if DRI2_MINOR < 1
54*61046927SAndroid Build Coastguard Worker #undef DRI2_MINOR
55*61046927SAndroid Build Coastguard Worker #define DRI2_MINOR 1
56*61046927SAndroid Build Coastguard Worker #define X_DRI2GetBuffersWithFormat 7
57*61046927SAndroid Build Coastguard Worker #endif
58*61046927SAndroid Build Coastguard Worker 
59*61046927SAndroid Build Coastguard Worker 
60*61046927SAndroid Build Coastguard Worker #if defined(__APPLE__) || defined(__MACOSX)
61*61046927SAndroid Build Coastguard Worker static char dri2ExtensionName[] = APPLEDRINAME;
62*61046927SAndroid Build Coastguard Worker #else
63*61046927SAndroid Build Coastguard Worker static char dri2ExtensionName[] = DRI2_NAME;
64*61046927SAndroid Build Coastguard Worker #endif
65*61046927SAndroid Build Coastguard Worker static XExtensionInfo _dri2Info_data;
66*61046927SAndroid Build Coastguard Worker static XExtensionInfo *dri2Info = &_dri2Info_data;
67*61046927SAndroid Build Coastguard Worker static XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info)
68*61046927SAndroid Build Coastguard Worker 
69*61046927SAndroid Build Coastguard Worker static Bool
70*61046927SAndroid Build Coastguard Worker DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire);
71*61046927SAndroid Build Coastguard Worker static Status
72*61046927SAndroid Build Coastguard Worker DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire);
73*61046927SAndroid Build Coastguard Worker static int
74*61046927SAndroid Build Coastguard Worker DRI2Error(Display *display, xError *err, XExtCodes *codes, int *ret_code);
75*61046927SAndroid Build Coastguard Worker 
76*61046927SAndroid Build Coastguard Worker static /* const */ XExtensionHooks dri2ExtensionHooks = {
77*61046927SAndroid Build Coastguard Worker   NULL,                   /* create_gc */
78*61046927SAndroid Build Coastguard Worker   NULL,                   /* copy_gc */
79*61046927SAndroid Build Coastguard Worker   NULL,                   /* flush_gc */
80*61046927SAndroid Build Coastguard Worker   NULL,                   /* free_gc */
81*61046927SAndroid Build Coastguard Worker   NULL,                   /* create_font */
82*61046927SAndroid Build Coastguard Worker   NULL,                   /* free_font */
83*61046927SAndroid Build Coastguard Worker   DRI2CloseDisplay,       /* close_display */
84*61046927SAndroid Build Coastguard Worker   DRI2WireToEvent,        /* wire_to_event */
85*61046927SAndroid Build Coastguard Worker   DRI2EventToWire,        /* event_to_wire */
86*61046927SAndroid Build Coastguard Worker   DRI2Error,              /* error */
87*61046927SAndroid Build Coastguard Worker   NULL,                   /* error_string */
88*61046927SAndroid Build Coastguard Worker };
89*61046927SAndroid Build Coastguard Worker 
90*61046927SAndroid Build Coastguard Worker static XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay,
91*61046927SAndroid Build Coastguard Worker                                    dri2Info,
92*61046927SAndroid Build Coastguard Worker                                    dri2ExtensionName,
93*61046927SAndroid Build Coastguard Worker                                    &dri2ExtensionHooks,
94*61046927SAndroid Build Coastguard Worker                                    0, NULL)
95*61046927SAndroid Build Coastguard Worker 
96*61046927SAndroid Build Coastguard Worker static Bool
DRI2WireToEvent(Display * dpy,XEvent * event,xEvent * wire)97*61046927SAndroid Build Coastguard Worker DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire)
98*61046927SAndroid Build Coastguard Worker {
99*61046927SAndroid Build Coastguard Worker #if defined(GLX_DIRECT_RENDERING) && (!defined(GLX_USE_APPLEGL) || defined(GLX_USE_APPLE))
100*61046927SAndroid Build Coastguard Worker    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
101*61046927SAndroid Build Coastguard Worker    struct glx_drawable *glxDraw;
102*61046927SAndroid Build Coastguard Worker 
103*61046927SAndroid Build Coastguard Worker    XextCheckExtension(dpy, info, dri2ExtensionName, False);
104*61046927SAndroid Build Coastguard Worker 
105*61046927SAndroid Build Coastguard Worker    switch ((wire->u.u.type & 0x7f) - info->codes->first_event) {
106*61046927SAndroid Build Coastguard Worker 
107*61046927SAndroid Build Coastguard Worker    case DRI2_BufferSwapComplete:
108*61046927SAndroid Build Coastguard Worker    {
109*61046927SAndroid Build Coastguard Worker       GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
110*61046927SAndroid Build Coastguard Worker       xDRI2BufferSwapComplete2 *awire = (xDRI2BufferSwapComplete2 *)wire;
111*61046927SAndroid Build Coastguard Worker       __GLXDRIdrawable *pdraw;
112*61046927SAndroid Build Coastguard Worker 
113*61046927SAndroid Build Coastguard Worker       pdraw = dri2GetGlxDrawableFromXDrawableId(dpy, awire->drawable);
114*61046927SAndroid Build Coastguard Worker       if (pdraw == NULL)
115*61046927SAndroid Build Coastguard Worker          return False;
116*61046927SAndroid Build Coastguard Worker 
117*61046927SAndroid Build Coastguard Worker       /* Ignore swap events if we're not looking for them */
118*61046927SAndroid Build Coastguard Worker       aevent->type = dri2GetSwapEventType(dpy, awire->drawable);
119*61046927SAndroid Build Coastguard Worker       if(!aevent->type)
120*61046927SAndroid Build Coastguard Worker          return False;
121*61046927SAndroid Build Coastguard Worker 
122*61046927SAndroid Build Coastguard Worker       aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire);
123*61046927SAndroid Build Coastguard Worker       aevent->send_event = (awire->type & 0x80) != 0;
124*61046927SAndroid Build Coastguard Worker       aevent->display = dpy;
125*61046927SAndroid Build Coastguard Worker       aevent->drawable = awire->drawable;
126*61046927SAndroid Build Coastguard Worker       switch (awire->event_type) {
127*61046927SAndroid Build Coastguard Worker       case DRI2_EXCHANGE_COMPLETE:
128*61046927SAndroid Build Coastguard Worker     aevent->event_type = GLX_EXCHANGE_COMPLETE_INTEL;
129*61046927SAndroid Build Coastguard Worker     break;
130*61046927SAndroid Build Coastguard Worker       case DRI2_BLIT_COMPLETE:
131*61046927SAndroid Build Coastguard Worker     aevent->event_type = GLX_COPY_COMPLETE_INTEL;
132*61046927SAndroid Build Coastguard Worker     break;
133*61046927SAndroid Build Coastguard Worker       case DRI2_FLIP_COMPLETE:
134*61046927SAndroid Build Coastguard Worker     aevent->event_type = GLX_FLIP_COMPLETE_INTEL;
135*61046927SAndroid Build Coastguard Worker     break;
136*61046927SAndroid Build Coastguard Worker       default:
137*61046927SAndroid Build Coastguard Worker     /* unknown swap completion type */
138*61046927SAndroid Build Coastguard Worker     return False;
139*61046927SAndroid Build Coastguard Worker       }
140*61046927SAndroid Build Coastguard Worker       aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo;
141*61046927SAndroid Build Coastguard Worker       aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo;
142*61046927SAndroid Build Coastguard Worker 
143*61046927SAndroid Build Coastguard Worker       glxDraw = GetGLXDrawable(dpy, pdraw->drawable);
144*61046927SAndroid Build Coastguard Worker       if (glxDraw != NULL) {
145*61046927SAndroid Build Coastguard Worker          if (awire->sbc < glxDraw->lastEventSbc)
146*61046927SAndroid Build Coastguard Worker             glxDraw->eventSbcWrap += 0x100000000;
147*61046927SAndroid Build Coastguard Worker          glxDraw->lastEventSbc = awire->sbc;
148*61046927SAndroid Build Coastguard Worker          aevent->sbc = awire->sbc + glxDraw->eventSbcWrap;
149*61046927SAndroid Build Coastguard Worker       } else {
150*61046927SAndroid Build Coastguard Worker          aevent->sbc = awire->sbc;
151*61046927SAndroid Build Coastguard Worker       }
152*61046927SAndroid Build Coastguard Worker 
153*61046927SAndroid Build Coastguard Worker       return True;
154*61046927SAndroid Build Coastguard Worker    }
155*61046927SAndroid Build Coastguard Worker    case DRI2_InvalidateBuffers:
156*61046927SAndroid Build Coastguard Worker    {
157*61046927SAndroid Build Coastguard Worker       xDRI2InvalidateBuffers *awire = (xDRI2InvalidateBuffers *)wire;
158*61046927SAndroid Build Coastguard Worker 
159*61046927SAndroid Build Coastguard Worker       dri2InvalidateBuffers(dpy, awire->drawable);
160*61046927SAndroid Build Coastguard Worker       return False;
161*61046927SAndroid Build Coastguard Worker    }
162*61046927SAndroid Build Coastguard Worker    default:
163*61046927SAndroid Build Coastguard Worker       /* client doesn't support server event */
164*61046927SAndroid Build Coastguard Worker       break;
165*61046927SAndroid Build Coastguard Worker    }
166*61046927SAndroid Build Coastguard Worker #endif
167*61046927SAndroid Build Coastguard Worker 
168*61046927SAndroid Build Coastguard Worker    return False;
169*61046927SAndroid Build Coastguard Worker }
170*61046927SAndroid Build Coastguard Worker 
171*61046927SAndroid Build Coastguard Worker /* We don't actually support this.  It doesn't make sense for clients to
172*61046927SAndroid Build Coastguard Worker  * send each other DRI2 events.
173*61046927SAndroid Build Coastguard Worker  */
174*61046927SAndroid Build Coastguard Worker static Status
DRI2EventToWire(Display * dpy,XEvent * event,xEvent * wire)175*61046927SAndroid Build Coastguard Worker DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire)
176*61046927SAndroid Build Coastguard Worker {
177*61046927SAndroid Build Coastguard Worker    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
178*61046927SAndroid Build Coastguard Worker 
179*61046927SAndroid Build Coastguard Worker    XextCheckExtension(dpy, info, dri2ExtensionName, False);
180*61046927SAndroid Build Coastguard Worker 
181*61046927SAndroid Build Coastguard Worker    switch (event->type) {
182*61046927SAndroid Build Coastguard Worker    default:
183*61046927SAndroid Build Coastguard Worker       /* client doesn't support server event */
184*61046927SAndroid Build Coastguard Worker       break;
185*61046927SAndroid Build Coastguard Worker    }
186*61046927SAndroid Build Coastguard Worker 
187*61046927SAndroid Build Coastguard Worker    return Success;
188*61046927SAndroid Build Coastguard Worker }
189*61046927SAndroid Build Coastguard Worker 
190*61046927SAndroid Build Coastguard Worker static int
DRI2Error(Display * display,xError * err,XExtCodes * codes,int * ret_code)191*61046927SAndroid Build Coastguard Worker DRI2Error(Display *display, xError *err, XExtCodes *codes, int *ret_code)
192*61046927SAndroid Build Coastguard Worker {
193*61046927SAndroid Build Coastguard Worker     if (err->majorCode == codes->major_opcode &&
194*61046927SAndroid Build Coastguard Worker    err->errorCode == BadDrawable &&
195*61046927SAndroid Build Coastguard Worker    err->minorCode == X_DRI2CopyRegion)
196*61046927SAndroid Build Coastguard Worker    return True;
197*61046927SAndroid Build Coastguard Worker 
198*61046927SAndroid Build Coastguard Worker     /* If the X drawable was destroyed before the GLX drawable, the
199*61046927SAndroid Build Coastguard Worker      * DRI2 drawble will be gone by the time we call
200*61046927SAndroid Build Coastguard Worker      * DRI2DestroyDrawable.  So just ignore BadDrawable here. */
201*61046927SAndroid Build Coastguard Worker     if (err->majorCode == codes->major_opcode &&
202*61046927SAndroid Build Coastguard Worker    err->errorCode == BadDrawable &&
203*61046927SAndroid Build Coastguard Worker    err->minorCode == X_DRI2DestroyDrawable)
204*61046927SAndroid Build Coastguard Worker    return True;
205*61046927SAndroid Build Coastguard Worker 
206*61046927SAndroid Build Coastguard Worker     /* If the server is non-local DRI2Connect will raise BadRequest.
207*61046927SAndroid Build Coastguard Worker      * Swallow this so that DRI2Connect can signal this in its return code */
208*61046927SAndroid Build Coastguard Worker     if (err->majorCode == codes->major_opcode &&
209*61046927SAndroid Build Coastguard Worker         err->minorCode == X_DRI2Connect &&
210*61046927SAndroid Build Coastguard Worker         err->errorCode == BadRequest) {
211*61046927SAndroid Build Coastguard Worker    *ret_code = False;
212*61046927SAndroid Build Coastguard Worker    return True;
213*61046927SAndroid Build Coastguard Worker     }
214*61046927SAndroid Build Coastguard Worker 
215*61046927SAndroid Build Coastguard Worker     return False;
216*61046927SAndroid Build Coastguard Worker }
217*61046927SAndroid Build Coastguard Worker 
218*61046927SAndroid Build Coastguard Worker Bool
DRI2QueryExtension(Display * dpy,int * eventBase,int * errorBase)219*61046927SAndroid Build Coastguard Worker DRI2QueryExtension(Display * dpy, int *eventBase, int *errorBase)
220*61046927SAndroid Build Coastguard Worker {
221*61046927SAndroid Build Coastguard Worker #if defined(__APPLE__) || defined(__MACOSX)
222*61046927SAndroid Build Coastguard Worker    return XAppleDRIQueryExtension(dpy, eventBase, errorBase);
223*61046927SAndroid Build Coastguard Worker #else
224*61046927SAndroid Build Coastguard Worker    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
225*61046927SAndroid Build Coastguard Worker 
226*61046927SAndroid Build Coastguard Worker    if (XextHasExtension(info)) {
227*61046927SAndroid Build Coastguard Worker       *eventBase = info->codes->first_event;
228*61046927SAndroid Build Coastguard Worker       *errorBase = info->codes->first_error;
229*61046927SAndroid Build Coastguard Worker       return True;
230*61046927SAndroid Build Coastguard Worker    }
231*61046927SAndroid Build Coastguard Worker 
232*61046927SAndroid Build Coastguard Worker    return False;
233*61046927SAndroid Build Coastguard Worker #endif
234*61046927SAndroid Build Coastguard Worker }
235*61046927SAndroid Build Coastguard Worker 
236*61046927SAndroid Build Coastguard Worker Bool
DRI2QueryVersion(Display * dpy,int * major,int * minor)237*61046927SAndroid Build Coastguard Worker DRI2QueryVersion(Display * dpy, int *major, int *minor)
238*61046927SAndroid Build Coastguard Worker {
239*61046927SAndroid Build Coastguard Worker #if defined(__APPLE__) || defined(__MACOSX)
240*61046927SAndroid Build Coastguard Worker   int patch;
241*61046927SAndroid Build Coastguard Worker   return XAppleDRIQueryVersion(dpy, major, minor, &patch);
242*61046927SAndroid Build Coastguard Worker #else
243*61046927SAndroid Build Coastguard Worker    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
244*61046927SAndroid Build Coastguard Worker    xDRI2QueryVersionReply rep;
245*61046927SAndroid Build Coastguard Worker    xDRI2QueryVersionReq *req;
246*61046927SAndroid Build Coastguard Worker    int i, nevents;
247*61046927SAndroid Build Coastguard Worker 
248*61046927SAndroid Build Coastguard Worker    XextCheckExtension(dpy, info, dri2ExtensionName, False);
249*61046927SAndroid Build Coastguard Worker 
250*61046927SAndroid Build Coastguard Worker    LockDisplay(dpy);
251*61046927SAndroid Build Coastguard Worker    GetReq(DRI2QueryVersion, req);
252*61046927SAndroid Build Coastguard Worker    req->reqType = info->codes->major_opcode;
253*61046927SAndroid Build Coastguard Worker    req->dri2ReqType = X_DRI2QueryVersion;
254*61046927SAndroid Build Coastguard Worker    req->majorVersion = DRI2_MAJOR;
255*61046927SAndroid Build Coastguard Worker    req->minorVersion = DRI2_MINOR;
256*61046927SAndroid Build Coastguard Worker    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
257*61046927SAndroid Build Coastguard Worker       UnlockDisplay(dpy);
258*61046927SAndroid Build Coastguard Worker       SyncHandle();
259*61046927SAndroid Build Coastguard Worker       return False;
260*61046927SAndroid Build Coastguard Worker    }
261*61046927SAndroid Build Coastguard Worker    *major = rep.majorVersion;
262*61046927SAndroid Build Coastguard Worker    *minor = rep.minorVersion;
263*61046927SAndroid Build Coastguard Worker    UnlockDisplay(dpy);
264*61046927SAndroid Build Coastguard Worker    SyncHandle();
265*61046927SAndroid Build Coastguard Worker 
266*61046927SAndroid Build Coastguard Worker    switch (rep.minorVersion) {
267*61046927SAndroid Build Coastguard Worker    case 1:
268*61046927SAndroid Build Coastguard Worker       nevents = 0;
269*61046927SAndroid Build Coastguard Worker       break;
270*61046927SAndroid Build Coastguard Worker    case 2:
271*61046927SAndroid Build Coastguard Worker       nevents = 1;
272*61046927SAndroid Build Coastguard Worker       break;
273*61046927SAndroid Build Coastguard Worker    case 3:
274*61046927SAndroid Build Coastguard Worker    default:
275*61046927SAndroid Build Coastguard Worker       nevents = 2;
276*61046927SAndroid Build Coastguard Worker       break;
277*61046927SAndroid Build Coastguard Worker    }
278*61046927SAndroid Build Coastguard Worker 
279*61046927SAndroid Build Coastguard Worker    for (i = 0; i < nevents; i++) {
280*61046927SAndroid Build Coastguard Worker        XESetWireToEvent (dpy, info->codes->first_event + i, DRI2WireToEvent);
281*61046927SAndroid Build Coastguard Worker        XESetEventToWire (dpy, info->codes->first_event + i, DRI2EventToWire);
282*61046927SAndroid Build Coastguard Worker    }
283*61046927SAndroid Build Coastguard Worker 
284*61046927SAndroid Build Coastguard Worker    return True;
285*61046927SAndroid Build Coastguard Worker #endif
286*61046927SAndroid Build Coastguard Worker }
287*61046927SAndroid Build Coastguard Worker 
288*61046927SAndroid Build Coastguard Worker Bool
DRI2Connect(Display * dpy,XID window,char ** driverName,char ** deviceName)289*61046927SAndroid Build Coastguard Worker DRI2Connect(Display * dpy, XID window, char **driverName, char **deviceName)
290*61046927SAndroid Build Coastguard Worker {
291*61046927SAndroid Build Coastguard Worker    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
292*61046927SAndroid Build Coastguard Worker    xDRI2ConnectReply rep;
293*61046927SAndroid Build Coastguard Worker    xDRI2ConnectReq *req;
294*61046927SAndroid Build Coastguard Worker 
295*61046927SAndroid Build Coastguard Worker    XextCheckExtension(dpy, info, dri2ExtensionName, False);
296*61046927SAndroid Build Coastguard Worker 
297*61046927SAndroid Build Coastguard Worker    LockDisplay(dpy);
298*61046927SAndroid Build Coastguard Worker    GetReq(DRI2Connect, req);
299*61046927SAndroid Build Coastguard Worker    req->reqType = info->codes->major_opcode;
300*61046927SAndroid Build Coastguard Worker    req->dri2ReqType = X_DRI2Connect;
301*61046927SAndroid Build Coastguard Worker    req->window = window;
302*61046927SAndroid Build Coastguard Worker 
303*61046927SAndroid Build Coastguard Worker    req->driverType = DRI2DriverDRI;
304*61046927SAndroid Build Coastguard Worker    {
305*61046927SAndroid Build Coastguard Worker       char *prime = getenv("DRI_PRIME");
306*61046927SAndroid Build Coastguard Worker       if (prime) {
307*61046927SAndroid Build Coastguard Worker          uint32_t primeid;
308*61046927SAndroid Build Coastguard Worker          errno = 0;
309*61046927SAndroid Build Coastguard Worker          primeid = strtoul(prime, NULL, 0);
310*61046927SAndroid Build Coastguard Worker          if (errno == 0)
311*61046927SAndroid Build Coastguard Worker             req->driverType |=
312*61046927SAndroid Build Coastguard Worker                ((primeid & DRI2DriverPrimeMask) << DRI2DriverPrimeShift);
313*61046927SAndroid Build Coastguard Worker       }
314*61046927SAndroid Build Coastguard Worker    }
315*61046927SAndroid Build Coastguard Worker 
316*61046927SAndroid Build Coastguard Worker    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
317*61046927SAndroid Build Coastguard Worker       UnlockDisplay(dpy);
318*61046927SAndroid Build Coastguard Worker       SyncHandle();
319*61046927SAndroid Build Coastguard Worker       return False;
320*61046927SAndroid Build Coastguard Worker    }
321*61046927SAndroid Build Coastguard Worker 
322*61046927SAndroid Build Coastguard Worker    if (rep.driverNameLength == 0 && rep.deviceNameLength == 0) {
323*61046927SAndroid Build Coastguard Worker       UnlockDisplay(dpy);
324*61046927SAndroid Build Coastguard Worker       SyncHandle();
325*61046927SAndroid Build Coastguard Worker       return False;
326*61046927SAndroid Build Coastguard Worker    }
327*61046927SAndroid Build Coastguard Worker 
328*61046927SAndroid Build Coastguard Worker    *driverName = malloc(rep.driverNameLength + 1);
329*61046927SAndroid Build Coastguard Worker    if (*driverName == NULL) {
330*61046927SAndroid Build Coastguard Worker       _XEatData(dpy,
331*61046927SAndroid Build Coastguard Worker                 ((rep.driverNameLength + 3) & ~3) +
332*61046927SAndroid Build Coastguard Worker                 ((rep.deviceNameLength + 3) & ~3));
333*61046927SAndroid Build Coastguard Worker       UnlockDisplay(dpy);
334*61046927SAndroid Build Coastguard Worker       SyncHandle();
335*61046927SAndroid Build Coastguard Worker       return False;
336*61046927SAndroid Build Coastguard Worker    }
337*61046927SAndroid Build Coastguard Worker    _XReadPad(dpy, *driverName, rep.driverNameLength);
338*61046927SAndroid Build Coastguard Worker    (*driverName)[rep.driverNameLength] = '\0';
339*61046927SAndroid Build Coastguard Worker 
340*61046927SAndroid Build Coastguard Worker    *deviceName = malloc(rep.deviceNameLength + 1);
341*61046927SAndroid Build Coastguard Worker    if (*deviceName == NULL) {
342*61046927SAndroid Build Coastguard Worker       free(*driverName);
343*61046927SAndroid Build Coastguard Worker       _XEatData(dpy, ((rep.deviceNameLength + 3) & ~3));
344*61046927SAndroid Build Coastguard Worker       UnlockDisplay(dpy);
345*61046927SAndroid Build Coastguard Worker       SyncHandle();
346*61046927SAndroid Build Coastguard Worker       return False;
347*61046927SAndroid Build Coastguard Worker    }
348*61046927SAndroid Build Coastguard Worker    _XReadPad(dpy, *deviceName, rep.deviceNameLength);
349*61046927SAndroid Build Coastguard Worker    (*deviceName)[rep.deviceNameLength] = '\0';
350*61046927SAndroid Build Coastguard Worker 
351*61046927SAndroid Build Coastguard Worker    UnlockDisplay(dpy);
352*61046927SAndroid Build Coastguard Worker    SyncHandle();
353*61046927SAndroid Build Coastguard Worker 
354*61046927SAndroid Build Coastguard Worker    return True;
355*61046927SAndroid Build Coastguard Worker }
356*61046927SAndroid Build Coastguard Worker 
357*61046927SAndroid Build Coastguard Worker Bool
DRI2Authenticate(Display * dpy,XID window,drm_magic_t magic)358*61046927SAndroid Build Coastguard Worker DRI2Authenticate(Display * dpy, XID window, drm_magic_t magic)
359*61046927SAndroid Build Coastguard Worker {
360*61046927SAndroid Build Coastguard Worker    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
361*61046927SAndroid Build Coastguard Worker    xDRI2AuthenticateReq *req;
362*61046927SAndroid Build Coastguard Worker    xDRI2AuthenticateReply rep;
363*61046927SAndroid Build Coastguard Worker 
364*61046927SAndroid Build Coastguard Worker    XextCheckExtension(dpy, info, dri2ExtensionName, False);
365*61046927SAndroid Build Coastguard Worker 
366*61046927SAndroid Build Coastguard Worker    LockDisplay(dpy);
367*61046927SAndroid Build Coastguard Worker    GetReq(DRI2Authenticate, req);
368*61046927SAndroid Build Coastguard Worker    req->reqType = info->codes->major_opcode;
369*61046927SAndroid Build Coastguard Worker    req->dri2ReqType = X_DRI2Authenticate;
370*61046927SAndroid Build Coastguard Worker    req->window = window;
371*61046927SAndroid Build Coastguard Worker    req->magic = magic;
372*61046927SAndroid Build Coastguard Worker 
373*61046927SAndroid Build Coastguard Worker    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
374*61046927SAndroid Build Coastguard Worker       UnlockDisplay(dpy);
375*61046927SAndroid Build Coastguard Worker       SyncHandle();
376*61046927SAndroid Build Coastguard Worker       return False;
377*61046927SAndroid Build Coastguard Worker    }
378*61046927SAndroid Build Coastguard Worker 
379*61046927SAndroid Build Coastguard Worker    UnlockDisplay(dpy);
380*61046927SAndroid Build Coastguard Worker    SyncHandle();
381*61046927SAndroid Build Coastguard Worker 
382*61046927SAndroid Build Coastguard Worker    return rep.authenticated;
383*61046927SAndroid Build Coastguard Worker }
384*61046927SAndroid Build Coastguard Worker 
385*61046927SAndroid Build Coastguard Worker void
DRI2CreateDrawable(Display * dpy,XID drawable)386*61046927SAndroid Build Coastguard Worker DRI2CreateDrawable(Display * dpy, XID drawable)
387*61046927SAndroid Build Coastguard Worker {
388*61046927SAndroid Build Coastguard Worker    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
389*61046927SAndroid Build Coastguard Worker    xDRI2CreateDrawableReq *req;
390*61046927SAndroid Build Coastguard Worker 
391*61046927SAndroid Build Coastguard Worker    XextSimpleCheckExtension(dpy, info, dri2ExtensionName);
392*61046927SAndroid Build Coastguard Worker 
393*61046927SAndroid Build Coastguard Worker    LockDisplay(dpy);
394*61046927SAndroid Build Coastguard Worker    GetReq(DRI2CreateDrawable, req);
395*61046927SAndroid Build Coastguard Worker    req->reqType = info->codes->major_opcode;
396*61046927SAndroid Build Coastguard Worker    req->dri2ReqType = X_DRI2CreateDrawable;
397*61046927SAndroid Build Coastguard Worker    req->drawable = drawable;
398*61046927SAndroid Build Coastguard Worker    UnlockDisplay(dpy);
399*61046927SAndroid Build Coastguard Worker    SyncHandle();
400*61046927SAndroid Build Coastguard Worker }
401*61046927SAndroid Build Coastguard Worker 
402*61046927SAndroid Build Coastguard Worker void
DRI2DestroyDrawable(Display * dpy,XID drawable)403*61046927SAndroid Build Coastguard Worker DRI2DestroyDrawable(Display * dpy, XID drawable)
404*61046927SAndroid Build Coastguard Worker {
405*61046927SAndroid Build Coastguard Worker    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
406*61046927SAndroid Build Coastguard Worker    xDRI2DestroyDrawableReq *req;
407*61046927SAndroid Build Coastguard Worker 
408*61046927SAndroid Build Coastguard Worker    XextSimpleCheckExtension(dpy, info, dri2ExtensionName);
409*61046927SAndroid Build Coastguard Worker 
410*61046927SAndroid Build Coastguard Worker    XSync(dpy, False);
411*61046927SAndroid Build Coastguard Worker 
412*61046927SAndroid Build Coastguard Worker    LockDisplay(dpy);
413*61046927SAndroid Build Coastguard Worker    GetReq(DRI2DestroyDrawable, req);
414*61046927SAndroid Build Coastguard Worker    req->reqType = info->codes->major_opcode;
415*61046927SAndroid Build Coastguard Worker    req->dri2ReqType = X_DRI2DestroyDrawable;
416*61046927SAndroid Build Coastguard Worker    req->drawable = drawable;
417*61046927SAndroid Build Coastguard Worker    UnlockDisplay(dpy);
418*61046927SAndroid Build Coastguard Worker    SyncHandle();
419*61046927SAndroid Build Coastguard Worker }
420*61046927SAndroid Build Coastguard Worker 
421*61046927SAndroid Build Coastguard Worker DRI2Buffer *
DRI2GetBuffers(Display * dpy,XID drawable,int * width,int * height,unsigned int * attachments,int count,int * outCount)422*61046927SAndroid Build Coastguard Worker DRI2GetBuffers(Display * dpy, XID drawable,
423*61046927SAndroid Build Coastguard Worker                int *width, int *height,
424*61046927SAndroid Build Coastguard Worker                unsigned int *attachments, int count, int *outCount)
425*61046927SAndroid Build Coastguard Worker {
426*61046927SAndroid Build Coastguard Worker    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
427*61046927SAndroid Build Coastguard Worker    xDRI2GetBuffersReply rep;
428*61046927SAndroid Build Coastguard Worker    xDRI2GetBuffersReq *req;
429*61046927SAndroid Build Coastguard Worker    DRI2Buffer *buffers;
430*61046927SAndroid Build Coastguard Worker    xDRI2Buffer repBuffer;
431*61046927SAndroid Build Coastguard Worker    CARD32 *p;
432*61046927SAndroid Build Coastguard Worker    int i;
433*61046927SAndroid Build Coastguard Worker 
434*61046927SAndroid Build Coastguard Worker    XextCheckExtension(dpy, info, dri2ExtensionName, NULL);
435*61046927SAndroid Build Coastguard Worker 
436*61046927SAndroid Build Coastguard Worker    LockDisplay(dpy);
437*61046927SAndroid Build Coastguard Worker    GetReqExtra(DRI2GetBuffers, count * 4, req);
438*61046927SAndroid Build Coastguard Worker    req->reqType = info->codes->major_opcode;
439*61046927SAndroid Build Coastguard Worker    req->dri2ReqType = X_DRI2GetBuffers;
440*61046927SAndroid Build Coastguard Worker    req->drawable = drawable;
441*61046927SAndroid Build Coastguard Worker    req->count = count;
442*61046927SAndroid Build Coastguard Worker    p = (CARD32 *) & req[1];
443*61046927SAndroid Build Coastguard Worker    for (i = 0; i < count; i++)
444*61046927SAndroid Build Coastguard Worker       p[i] = attachments[i];
445*61046927SAndroid Build Coastguard Worker 
446*61046927SAndroid Build Coastguard Worker    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
447*61046927SAndroid Build Coastguard Worker       UnlockDisplay(dpy);
448*61046927SAndroid Build Coastguard Worker       SyncHandle();
449*61046927SAndroid Build Coastguard Worker       return NULL;
450*61046927SAndroid Build Coastguard Worker    }
451*61046927SAndroid Build Coastguard Worker 
452*61046927SAndroid Build Coastguard Worker    *width = rep.width;
453*61046927SAndroid Build Coastguard Worker    *height = rep.height;
454*61046927SAndroid Build Coastguard Worker    *outCount = rep.count;
455*61046927SAndroid Build Coastguard Worker 
456*61046927SAndroid Build Coastguard Worker    buffers = malloc(rep.count * sizeof buffers[0]);
457*61046927SAndroid Build Coastguard Worker    if (buffers == NULL) {
458*61046927SAndroid Build Coastguard Worker       _XEatData(dpy, rep.count * sizeof repBuffer);
459*61046927SAndroid Build Coastguard Worker       UnlockDisplay(dpy);
460*61046927SAndroid Build Coastguard Worker       SyncHandle();
461*61046927SAndroid Build Coastguard Worker       return NULL;
462*61046927SAndroid Build Coastguard Worker    }
463*61046927SAndroid Build Coastguard Worker 
464*61046927SAndroid Build Coastguard Worker    for (i = 0; i < rep.count; i++) {
465*61046927SAndroid Build Coastguard Worker       _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer);
466*61046927SAndroid Build Coastguard Worker       buffers[i].attachment = repBuffer.attachment;
467*61046927SAndroid Build Coastguard Worker       buffers[i].name = repBuffer.name;
468*61046927SAndroid Build Coastguard Worker       buffers[i].pitch = repBuffer.pitch;
469*61046927SAndroid Build Coastguard Worker       buffers[i].cpp = repBuffer.cpp;
470*61046927SAndroid Build Coastguard Worker       buffers[i].flags = repBuffer.flags;
471*61046927SAndroid Build Coastguard Worker    }
472*61046927SAndroid Build Coastguard Worker 
473*61046927SAndroid Build Coastguard Worker    UnlockDisplay(dpy);
474*61046927SAndroid Build Coastguard Worker    SyncHandle();
475*61046927SAndroid Build Coastguard Worker 
476*61046927SAndroid Build Coastguard Worker    return buffers;
477*61046927SAndroid Build Coastguard Worker }
478*61046927SAndroid Build Coastguard Worker 
479*61046927SAndroid Build Coastguard Worker 
480*61046927SAndroid Build Coastguard Worker DRI2Buffer *
DRI2GetBuffersWithFormat(Display * dpy,XID drawable,int * width,int * height,unsigned int * attachments,int count,int * outCount)481*61046927SAndroid Build Coastguard Worker DRI2GetBuffersWithFormat(Display * dpy, XID drawable,
482*61046927SAndroid Build Coastguard Worker                          int *width, int *height,
483*61046927SAndroid Build Coastguard Worker                          unsigned int *attachments, int count, int *outCount)
484*61046927SAndroid Build Coastguard Worker {
485*61046927SAndroid Build Coastguard Worker    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
486*61046927SAndroid Build Coastguard Worker    xDRI2GetBuffersReply rep;
487*61046927SAndroid Build Coastguard Worker    xDRI2GetBuffersReq *req;
488*61046927SAndroid Build Coastguard Worker    DRI2Buffer *buffers;
489*61046927SAndroid Build Coastguard Worker    xDRI2Buffer repBuffer;
490*61046927SAndroid Build Coastguard Worker    CARD32 *p;
491*61046927SAndroid Build Coastguard Worker    int i;
492*61046927SAndroid Build Coastguard Worker 
493*61046927SAndroid Build Coastguard Worker    XextCheckExtension(dpy, info, dri2ExtensionName, NULL);
494*61046927SAndroid Build Coastguard Worker 
495*61046927SAndroid Build Coastguard Worker    LockDisplay(dpy);
496*61046927SAndroid Build Coastguard Worker    GetReqExtra(DRI2GetBuffers, count * (4 * 2), req);
497*61046927SAndroid Build Coastguard Worker    req->reqType = info->codes->major_opcode;
498*61046927SAndroid Build Coastguard Worker    req->dri2ReqType = X_DRI2GetBuffersWithFormat;
499*61046927SAndroid Build Coastguard Worker    req->drawable = drawable;
500*61046927SAndroid Build Coastguard Worker    req->count = count;
501*61046927SAndroid Build Coastguard Worker    p = (CARD32 *) & req[1];
502*61046927SAndroid Build Coastguard Worker    for (i = 0; i < (count * 2); i++)
503*61046927SAndroid Build Coastguard Worker       p[i] = attachments[i];
504*61046927SAndroid Build Coastguard Worker 
505*61046927SAndroid Build Coastguard Worker    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
506*61046927SAndroid Build Coastguard Worker       UnlockDisplay(dpy);
507*61046927SAndroid Build Coastguard Worker       SyncHandle();
508*61046927SAndroid Build Coastguard Worker       return NULL;
509*61046927SAndroid Build Coastguard Worker    }
510*61046927SAndroid Build Coastguard Worker 
511*61046927SAndroid Build Coastguard Worker    *width = rep.width;
512*61046927SAndroid Build Coastguard Worker    *height = rep.height;
513*61046927SAndroid Build Coastguard Worker    *outCount = rep.count;
514*61046927SAndroid Build Coastguard Worker 
515*61046927SAndroid Build Coastguard Worker    buffers = malloc(rep.count * sizeof buffers[0]);
516*61046927SAndroid Build Coastguard Worker    if (buffers == NULL) {
517*61046927SAndroid Build Coastguard Worker       _XEatData(dpy, rep.count * sizeof repBuffer);
518*61046927SAndroid Build Coastguard Worker       UnlockDisplay(dpy);
519*61046927SAndroid Build Coastguard Worker       SyncHandle();
520*61046927SAndroid Build Coastguard Worker       return NULL;
521*61046927SAndroid Build Coastguard Worker    }
522*61046927SAndroid Build Coastguard Worker 
523*61046927SAndroid Build Coastguard Worker    for (i = 0; i < rep.count; i++) {
524*61046927SAndroid Build Coastguard Worker       _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer);
525*61046927SAndroid Build Coastguard Worker       buffers[i].attachment = repBuffer.attachment;
526*61046927SAndroid Build Coastguard Worker       buffers[i].name = repBuffer.name;
527*61046927SAndroid Build Coastguard Worker       buffers[i].pitch = repBuffer.pitch;
528*61046927SAndroid Build Coastguard Worker       buffers[i].cpp = repBuffer.cpp;
529*61046927SAndroid Build Coastguard Worker       buffers[i].flags = repBuffer.flags;
530*61046927SAndroid Build Coastguard Worker    }
531*61046927SAndroid Build Coastguard Worker 
532*61046927SAndroid Build Coastguard Worker    UnlockDisplay(dpy);
533*61046927SAndroid Build Coastguard Worker    SyncHandle();
534*61046927SAndroid Build Coastguard Worker 
535*61046927SAndroid Build Coastguard Worker    return buffers;
536*61046927SAndroid Build Coastguard Worker }
537*61046927SAndroid Build Coastguard Worker 
538*61046927SAndroid Build Coastguard Worker 
539*61046927SAndroid Build Coastguard Worker void
DRI2CopyRegion(Display * dpy,XID drawable,XserverRegion region,CARD32 dest,CARD32 src)540*61046927SAndroid Build Coastguard Worker DRI2CopyRegion(Display * dpy, XID drawable, XserverRegion region,
541*61046927SAndroid Build Coastguard Worker                CARD32 dest, CARD32 src)
542*61046927SAndroid Build Coastguard Worker {
543*61046927SAndroid Build Coastguard Worker    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
544*61046927SAndroid Build Coastguard Worker    xDRI2CopyRegionReq *req;
545*61046927SAndroid Build Coastguard Worker    xDRI2CopyRegionReply rep;
546*61046927SAndroid Build Coastguard Worker 
547*61046927SAndroid Build Coastguard Worker    XextSimpleCheckExtension(dpy, info, dri2ExtensionName);
548*61046927SAndroid Build Coastguard Worker 
549*61046927SAndroid Build Coastguard Worker    LockDisplay(dpy);
550*61046927SAndroid Build Coastguard Worker    GetReq(DRI2CopyRegion, req);
551*61046927SAndroid Build Coastguard Worker    req->reqType = info->codes->major_opcode;
552*61046927SAndroid Build Coastguard Worker    req->dri2ReqType = X_DRI2CopyRegion;
553*61046927SAndroid Build Coastguard Worker    req->drawable = drawable;
554*61046927SAndroid Build Coastguard Worker    req->region = region;
555*61046927SAndroid Build Coastguard Worker    req->dest = dest;
556*61046927SAndroid Build Coastguard Worker    req->src = src;
557*61046927SAndroid Build Coastguard Worker 
558*61046927SAndroid Build Coastguard Worker    _XReply(dpy, (xReply *) & rep, 0, xFalse);
559*61046927SAndroid Build Coastguard Worker 
560*61046927SAndroid Build Coastguard Worker    UnlockDisplay(dpy);
561*61046927SAndroid Build Coastguard Worker    SyncHandle();
562*61046927SAndroid Build Coastguard Worker }
563*61046927SAndroid Build Coastguard Worker 
564*61046927SAndroid Build Coastguard Worker #endif /* GLX_DIRECT_RENDERING */
565