xref: /aosp_15_r20/external/mesa3d/src/glx/glxext.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3*61046927SAndroid Build Coastguard Worker  * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
4*61046927SAndroid Build Coastguard Worker  *
5*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: SGI-B-2.0
6*61046927SAndroid Build Coastguard Worker  */
7*61046927SAndroid Build Coastguard Worker 
8*61046927SAndroid Build Coastguard Worker /**
9*61046927SAndroid Build Coastguard Worker  * \file glxext.c
10*61046927SAndroid Build Coastguard Worker  * GLX protocol interface boot-strap code.
11*61046927SAndroid Build Coastguard Worker  *
12*61046927SAndroid Build Coastguard Worker  * Direct rendering support added by Precision Insight, Inc.
13*61046927SAndroid Build Coastguard Worker  *
14*61046927SAndroid Build Coastguard Worker  * \author Kevin E. Martin <[email protected]>
15*61046927SAndroid Build Coastguard Worker  */
16*61046927SAndroid Build Coastguard Worker 
17*61046927SAndroid Build Coastguard Worker #include <assert.h>
18*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
19*61046927SAndroid Build Coastguard Worker #include <stdarg.h>
20*61046927SAndroid Build Coastguard Worker 
21*61046927SAndroid Build Coastguard Worker #include "glxclient.h"
22*61046927SAndroid Build Coastguard Worker #include <X11/extensions/Xext.h>
23*61046927SAndroid Build Coastguard Worker #include <X11/extensions/extutil.h>
24*61046927SAndroid Build Coastguard Worker #ifdef GLX_USE_APPLEGL
25*61046927SAndroid Build Coastguard Worker #include "apple/apple_glx.h"
26*61046927SAndroid Build Coastguard Worker #include "apple/apple_visual.h"
27*61046927SAndroid Build Coastguard Worker #endif
28*61046927SAndroid Build Coastguard Worker #include "glxextensions.h"
29*61046927SAndroid Build Coastguard Worker 
30*61046927SAndroid Build Coastguard Worker #include "util/u_debug.h"
31*61046927SAndroid Build Coastguard Worker #ifndef GLX_USE_APPLEGL
32*61046927SAndroid Build Coastguard Worker #include "dri_common.h"
33*61046927SAndroid Build Coastguard Worker #endif
34*61046927SAndroid Build Coastguard Worker 
35*61046927SAndroid Build Coastguard Worker #include "loader_x11.h"
36*61046927SAndroid Build Coastguard Worker #ifdef HAVE_LIBDRM
37*61046927SAndroid Build Coastguard Worker #include "loader_dri3_helper.h"
38*61046927SAndroid Build Coastguard Worker #endif
39*61046927SAndroid Build Coastguard Worker 
40*61046927SAndroid Build Coastguard Worker #include <X11/Xlib-xcb.h>
41*61046927SAndroid Build Coastguard Worker #include <xcb/xcb.h>
42*61046927SAndroid Build Coastguard Worker #include <xcb/glx.h>
43*61046927SAndroid Build Coastguard Worker #include "dri_util.h"
44*61046927SAndroid Build Coastguard Worker #if defined(GLX_DIRECT_RENDERING) && (!defined(GLX_USE_APPLEGL) || defined(GLX_USE_APPLE))
45*61046927SAndroid Build Coastguard Worker #include <dlfcn.h>
46*61046927SAndroid Build Coastguard Worker #endif
47*61046927SAndroid Build Coastguard Worker 
48*61046927SAndroid Build Coastguard Worker #define __GLX_MIN_CONFIG_PROPS	18
49*61046927SAndroid Build Coastguard Worker #define __GLX_EXT_CONFIG_PROPS	32
50*61046927SAndroid Build Coastguard Worker 
51*61046927SAndroid Build Coastguard Worker /*
52*61046927SAndroid Build Coastguard Worker ** Since we send all non-core visual properties as token, value pairs,
53*61046927SAndroid Build Coastguard Worker ** we require 2 words across the wire. In order to maintain backwards
54*61046927SAndroid Build Coastguard Worker ** compatibility, we need to send the total number of words that the
55*61046927SAndroid Build Coastguard Worker ** VisualConfigs are sent back in so old libraries can simply "ignore"
56*61046927SAndroid Build Coastguard Worker ** the new properties.
57*61046927SAndroid Build Coastguard Worker */
58*61046927SAndroid Build Coastguard Worker #define __GLX_TOTAL_CONFIG \
59*61046927SAndroid Build Coastguard Worker    (__GLX_MIN_CONFIG_PROPS + 2 * __GLX_EXT_CONFIG_PROPS)
60*61046927SAndroid Build Coastguard Worker 
61*61046927SAndroid Build Coastguard Worker _X_HIDDEN void
glx_message(int level,const char * f,...)62*61046927SAndroid Build Coastguard Worker glx_message(int level, const char *f, ...)
63*61046927SAndroid Build Coastguard Worker {
64*61046927SAndroid Build Coastguard Worker    va_list args;
65*61046927SAndroid Build Coastguard Worker    int threshold = _LOADER_WARNING;
66*61046927SAndroid Build Coastguard Worker    const char *libgl_debug;
67*61046927SAndroid Build Coastguard Worker 
68*61046927SAndroid Build Coastguard Worker    libgl_debug = getenv("LIBGL_DEBUG");
69*61046927SAndroid Build Coastguard Worker    if (libgl_debug) {
70*61046927SAndroid Build Coastguard Worker       if (strstr(libgl_debug, "quiet"))
71*61046927SAndroid Build Coastguard Worker          threshold = _LOADER_FATAL;
72*61046927SAndroid Build Coastguard Worker       else if (strstr(libgl_debug, "verbose"))
73*61046927SAndroid Build Coastguard Worker          threshold = _LOADER_DEBUG;
74*61046927SAndroid Build Coastguard Worker    }
75*61046927SAndroid Build Coastguard Worker 
76*61046927SAndroid Build Coastguard Worker    /* Note that the _LOADER_* levels are lower numbers for more severe. */
77*61046927SAndroid Build Coastguard Worker    if (level <= threshold) {
78*61046927SAndroid Build Coastguard Worker       va_start(args, f);
79*61046927SAndroid Build Coastguard Worker       vfprintf(stderr, f, args);
80*61046927SAndroid Build Coastguard Worker       va_end(args);
81*61046927SAndroid Build Coastguard Worker    }
82*61046927SAndroid Build Coastguard Worker }
83*61046927SAndroid Build Coastguard Worker 
84*61046927SAndroid Build Coastguard Worker /*
85*61046927SAndroid Build Coastguard Worker ** You can set this cell to 1 to force the gl drawing stuff to be
86*61046927SAndroid Build Coastguard Worker ** one command per packet
87*61046927SAndroid Build Coastguard Worker */
88*61046927SAndroid Build Coastguard Worker _X_HIDDEN int __glXDebug = 0;
89*61046927SAndroid Build Coastguard Worker 
90*61046927SAndroid Build Coastguard Worker /* Extension required boiler plate */
91*61046927SAndroid Build Coastguard Worker 
92*61046927SAndroid Build Coastguard Worker static const char __glXExtensionName[] = GLX_EXTENSION_NAME;
93*61046927SAndroid Build Coastguard Worker static struct glx_display *glx_displays;
94*61046927SAndroid Build Coastguard Worker 
95*61046927SAndroid Build Coastguard Worker static /* const */ char *error_list[] = {
96*61046927SAndroid Build Coastguard Worker    "GLXBadContext",
97*61046927SAndroid Build Coastguard Worker    "GLXBadContextState",
98*61046927SAndroid Build Coastguard Worker    "GLXBadDrawable",
99*61046927SAndroid Build Coastguard Worker    "GLXBadPixmap",
100*61046927SAndroid Build Coastguard Worker    "GLXBadContextTag",
101*61046927SAndroid Build Coastguard Worker    "GLXBadCurrentWindow",
102*61046927SAndroid Build Coastguard Worker    "GLXBadRenderRequest",
103*61046927SAndroid Build Coastguard Worker    "GLXBadLargeRequest",
104*61046927SAndroid Build Coastguard Worker    "GLXUnsupportedPrivateRequest",
105*61046927SAndroid Build Coastguard Worker    "GLXBadFBConfig",
106*61046927SAndroid Build Coastguard Worker    "GLXBadPbuffer",
107*61046927SAndroid Build Coastguard Worker    "GLXBadCurrentDrawable",
108*61046927SAndroid Build Coastguard Worker    "GLXBadWindow",
109*61046927SAndroid Build Coastguard Worker    "GLXBadProfileARB",
110*61046927SAndroid Build Coastguard Worker };
111*61046927SAndroid Build Coastguard Worker 
112*61046927SAndroid Build Coastguard Worker #ifdef GLX_USE_APPLEGL
113*61046927SAndroid Build Coastguard Worker static char *__glXErrorString(Display *dpy, int code, XExtCodes *codes,
114*61046927SAndroid Build Coastguard Worker                               char *buf, int n);
115*61046927SAndroid Build Coastguard Worker #endif
116*61046927SAndroid Build Coastguard Worker 
117*61046927SAndroid Build Coastguard Worker static
XEXT_GENERATE_ERROR_STRING(__glXErrorString,__glXExtensionName,__GLX_NUMBER_ERRORS,error_list)118*61046927SAndroid Build Coastguard Worker XEXT_GENERATE_ERROR_STRING(__glXErrorString, __glXExtensionName,
119*61046927SAndroid Build Coastguard Worker                            __GLX_NUMBER_ERRORS, error_list)
120*61046927SAndroid Build Coastguard Worker 
121*61046927SAndroid Build Coastguard Worker /*
122*61046927SAndroid Build Coastguard Worker  * GLX events are a bit funky.  We don't stuff the X event code into
123*61046927SAndroid Build Coastguard Worker  * our user exposed (via XNextEvent) structure.  Instead we use the GLX
124*61046927SAndroid Build Coastguard Worker  * private event code namespace (and hope it doesn't conflict).  Clients
125*61046927SAndroid Build Coastguard Worker  * have to know that bit 15 in the event type field means they're getting
126*61046927SAndroid Build Coastguard Worker  * a GLX event, and then handle the various sub-event types there, rather
127*61046927SAndroid Build Coastguard Worker  * than simply checking the event code and handling it directly.
128*61046927SAndroid Build Coastguard Worker  */
129*61046927SAndroid Build Coastguard Worker 
130*61046927SAndroid Build Coastguard Worker static Bool
131*61046927SAndroid Build Coastguard Worker __glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
132*61046927SAndroid Build Coastguard Worker {
133*61046927SAndroid Build Coastguard Worker      struct glx_display *glx_dpy = __glXInitialize(dpy);
134*61046927SAndroid Build Coastguard Worker 
135*61046927SAndroid Build Coastguard Worker    if (glx_dpy == NULL)
136*61046927SAndroid Build Coastguard Worker       return False;
137*61046927SAndroid Build Coastguard Worker 
138*61046927SAndroid Build Coastguard Worker    switch ((wire->u.u.type & 0x7f) - glx_dpy->codes.first_event) {
139*61046927SAndroid Build Coastguard Worker    case GLX_PbufferClobber:
140*61046927SAndroid Build Coastguard Worker    {
141*61046927SAndroid Build Coastguard Worker       GLXPbufferClobberEvent *aevent = (GLXPbufferClobberEvent *)event;
142*61046927SAndroid Build Coastguard Worker       xGLXPbufferClobberEvent *awire = (xGLXPbufferClobberEvent *)wire;
143*61046927SAndroid Build Coastguard Worker       aevent->event_type = awire->event_type;
144*61046927SAndroid Build Coastguard Worker       aevent->serial = awire->sequenceNumber;
145*61046927SAndroid Build Coastguard Worker       aevent->draw_type = awire->draw_type;
146*61046927SAndroid Build Coastguard Worker       aevent->drawable = awire->drawable;
147*61046927SAndroid Build Coastguard Worker       aevent->buffer_mask = awire->buffer_mask;
148*61046927SAndroid Build Coastguard Worker       aevent->aux_buffer = awire->aux_buffer;
149*61046927SAndroid Build Coastguard Worker       aevent->x = awire->x;
150*61046927SAndroid Build Coastguard Worker       aevent->y = awire->y;
151*61046927SAndroid Build Coastguard Worker       aevent->width = awire->width;
152*61046927SAndroid Build Coastguard Worker       aevent->height = awire->height;
153*61046927SAndroid Build Coastguard Worker       aevent->count = awire->count;
154*61046927SAndroid Build Coastguard Worker       return True;
155*61046927SAndroid Build Coastguard Worker    }
156*61046927SAndroid Build Coastguard Worker    case GLX_BufferSwapComplete:
157*61046927SAndroid Build Coastguard Worker    {
158*61046927SAndroid Build Coastguard Worker       GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
159*61046927SAndroid Build Coastguard Worker       xGLXBufferSwapComplete2 *awire = (xGLXBufferSwapComplete2 *)wire;
160*61046927SAndroid Build Coastguard Worker       struct glx_drawable *glxDraw = GetGLXDrawable(dpy, awire->drawable);
161*61046927SAndroid Build Coastguard Worker 
162*61046927SAndroid Build Coastguard Worker       if (!glxDraw)
163*61046927SAndroid Build Coastguard Worker 	 return False;
164*61046927SAndroid Build Coastguard Worker 
165*61046927SAndroid Build Coastguard Worker       aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire);
166*61046927SAndroid Build Coastguard Worker       aevent->send_event = (awire->type & 0x80) != 0;
167*61046927SAndroid Build Coastguard Worker       aevent->display = dpy;
168*61046927SAndroid Build Coastguard Worker       aevent->event_type = awire->event_type;
169*61046927SAndroid Build Coastguard Worker       aevent->drawable = glxDraw->xDrawable;
170*61046927SAndroid Build Coastguard Worker       aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo;
171*61046927SAndroid Build Coastguard Worker       aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo;
172*61046927SAndroid Build Coastguard Worker 
173*61046927SAndroid Build Coastguard Worker       /* Handle 32-Bit wire sbc wraparound in both directions to cope with out
174*61046927SAndroid Build Coastguard Worker        * of sequence 64-Bit sbc's
175*61046927SAndroid Build Coastguard Worker        */
176*61046927SAndroid Build Coastguard Worker       if ((int64_t) awire->sbc < ((int64_t) glxDraw->lastEventSbc - 0x40000000))
177*61046927SAndroid Build Coastguard Worker          glxDraw->eventSbcWrap += 0x100000000;
178*61046927SAndroid Build Coastguard Worker       if ((int64_t) awire->sbc > ((int64_t) glxDraw->lastEventSbc + 0x40000000))
179*61046927SAndroid Build Coastguard Worker          glxDraw->eventSbcWrap -= 0x100000000;
180*61046927SAndroid Build Coastguard Worker       glxDraw->lastEventSbc = awire->sbc;
181*61046927SAndroid Build Coastguard Worker       aevent->sbc = awire->sbc + glxDraw->eventSbcWrap;
182*61046927SAndroid Build Coastguard Worker       return True;
183*61046927SAndroid Build Coastguard Worker    }
184*61046927SAndroid Build Coastguard Worker    default:
185*61046927SAndroid Build Coastguard Worker       /* client doesn't support server event */
186*61046927SAndroid Build Coastguard Worker       break;
187*61046927SAndroid Build Coastguard Worker    }
188*61046927SAndroid Build Coastguard Worker 
189*61046927SAndroid Build Coastguard Worker    return False;
190*61046927SAndroid Build Coastguard Worker }
191*61046927SAndroid Build Coastguard Worker 
192*61046927SAndroid Build Coastguard Worker /* We don't actually support this.  It doesn't make sense for clients to
193*61046927SAndroid Build Coastguard Worker  * send each other GLX events.
194*61046927SAndroid Build Coastguard Worker  */
195*61046927SAndroid Build Coastguard Worker static Status
__glXEventToWire(Display * dpy,XEvent * event,xEvent * wire)196*61046927SAndroid Build Coastguard Worker __glXEventToWire(Display *dpy, XEvent *event, xEvent *wire)
197*61046927SAndroid Build Coastguard Worker {
198*61046927SAndroid Build Coastguard Worker      struct glx_display *glx_dpy = __glXInitialize(dpy);
199*61046927SAndroid Build Coastguard Worker 
200*61046927SAndroid Build Coastguard Worker    if (glx_dpy == NULL)
201*61046927SAndroid Build Coastguard Worker       return False;
202*61046927SAndroid Build Coastguard Worker 
203*61046927SAndroid Build Coastguard Worker    switch (event->type) {
204*61046927SAndroid Build Coastguard Worker    case GLX_DAMAGED:
205*61046927SAndroid Build Coastguard Worker       break;
206*61046927SAndroid Build Coastguard Worker    case GLX_SAVED:
207*61046927SAndroid Build Coastguard Worker       break;
208*61046927SAndroid Build Coastguard Worker    case GLX_EXCHANGE_COMPLETE_INTEL:
209*61046927SAndroid Build Coastguard Worker       break;
210*61046927SAndroid Build Coastguard Worker    case GLX_COPY_COMPLETE_INTEL:
211*61046927SAndroid Build Coastguard Worker       break;
212*61046927SAndroid Build Coastguard Worker    case GLX_FLIP_COMPLETE_INTEL:
213*61046927SAndroid Build Coastguard Worker       break;
214*61046927SAndroid Build Coastguard Worker    default:
215*61046927SAndroid Build Coastguard Worker       /* client doesn't support server event */
216*61046927SAndroid Build Coastguard Worker       break;
217*61046927SAndroid Build Coastguard Worker    }
218*61046927SAndroid Build Coastguard Worker 
219*61046927SAndroid Build Coastguard Worker    return Success;
220*61046927SAndroid Build Coastguard Worker }
221*61046927SAndroid Build Coastguard Worker 
222*61046927SAndroid Build Coastguard Worker /************************************************************************/
223*61046927SAndroid Build Coastguard Worker /*
224*61046927SAndroid Build Coastguard Worker ** Free the per screen configs data as well as the array of
225*61046927SAndroid Build Coastguard Worker ** __glXScreenConfigs.
226*61046927SAndroid Build Coastguard Worker */
227*61046927SAndroid Build Coastguard Worker static void
FreeScreenConfigs(struct glx_display * priv)228*61046927SAndroid Build Coastguard Worker FreeScreenConfigs(struct glx_display * priv)
229*61046927SAndroid Build Coastguard Worker {
230*61046927SAndroid Build Coastguard Worker    struct glx_screen *psc;
231*61046927SAndroid Build Coastguard Worker    GLint i, screens;
232*61046927SAndroid Build Coastguard Worker 
233*61046927SAndroid Build Coastguard Worker    /* Free screen configuration information */
234*61046927SAndroid Build Coastguard Worker    screens = ScreenCount(priv->dpy);
235*61046927SAndroid Build Coastguard Worker    for (i = 0; i < screens; i++) {
236*61046927SAndroid Build Coastguard Worker       psc = priv->screens[i];
237*61046927SAndroid Build Coastguard Worker       if (!psc)
238*61046927SAndroid Build Coastguard Worker          continue;
239*61046927SAndroid Build Coastguard Worker       glx_screen_cleanup(psc);
240*61046927SAndroid Build Coastguard Worker 
241*61046927SAndroid Build Coastguard Worker #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
242*61046927SAndroid Build Coastguard Worker       if (psc->driScreen.deinitScreen)
243*61046927SAndroid Build Coastguard Worker          psc->driScreen.deinitScreen(psc);
244*61046927SAndroid Build Coastguard Worker       /* Free the direct rendering per screen data */
245*61046927SAndroid Build Coastguard Worker       driDestroyScreen(psc->frontend_screen);
246*61046927SAndroid Build Coastguard Worker #endif
247*61046927SAndroid Build Coastguard Worker       free(psc);
248*61046927SAndroid Build Coastguard Worker    }
249*61046927SAndroid Build Coastguard Worker    free((char *) priv->screens);
250*61046927SAndroid Build Coastguard Worker    priv->screens = NULL;
251*61046927SAndroid Build Coastguard Worker }
252*61046927SAndroid Build Coastguard Worker 
253*61046927SAndroid Build Coastguard Worker #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
254*61046927SAndroid Build Coastguard Worker static void
free_zombie_glx_drawable(struct set_entry * entry)255*61046927SAndroid Build Coastguard Worker free_zombie_glx_drawable(struct set_entry *entry)
256*61046927SAndroid Build Coastguard Worker {
257*61046927SAndroid Build Coastguard Worker    __GLXDRIdrawable *pdraw = (__GLXDRIdrawable *)entry->key;
258*61046927SAndroid Build Coastguard Worker 
259*61046927SAndroid Build Coastguard Worker    pdraw->destroyDrawable(pdraw);
260*61046927SAndroid Build Coastguard Worker }
261*61046927SAndroid Build Coastguard Worker #endif
262*61046927SAndroid Build Coastguard Worker 
263*61046927SAndroid Build Coastguard Worker static void
glx_display_free(struct glx_display * priv)264*61046927SAndroid Build Coastguard Worker glx_display_free(struct glx_display *priv)
265*61046927SAndroid Build Coastguard Worker {
266*61046927SAndroid Build Coastguard Worker    struct glx_context *gc;
267*61046927SAndroid Build Coastguard Worker 
268*61046927SAndroid Build Coastguard Worker    gc = __glXGetCurrentContext();
269*61046927SAndroid Build Coastguard Worker    if (priv->dpy == gc->currentDpy) {
270*61046927SAndroid Build Coastguard Worker       if (gc != &dummyContext)
271*61046927SAndroid Build Coastguard Worker          gc->vtable->unbind(gc);
272*61046927SAndroid Build Coastguard Worker 
273*61046927SAndroid Build Coastguard Worker       gc->vtable->destroy(gc);
274*61046927SAndroid Build Coastguard Worker       __glXSetCurrentContextNull();
275*61046927SAndroid Build Coastguard Worker    }
276*61046927SAndroid Build Coastguard Worker 
277*61046927SAndroid Build Coastguard Worker    /* Needs to be done before free screen. */
278*61046927SAndroid Build Coastguard Worker #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
279*61046927SAndroid Build Coastguard Worker    _mesa_set_destroy(priv->zombieGLXDrawable, free_zombie_glx_drawable);
280*61046927SAndroid Build Coastguard Worker #endif
281*61046927SAndroid Build Coastguard Worker 
282*61046927SAndroid Build Coastguard Worker    FreeScreenConfigs(priv);
283*61046927SAndroid Build Coastguard Worker 
284*61046927SAndroid Build Coastguard Worker    __glxHashDestroy(priv->glXDrawHash);
285*61046927SAndroid Build Coastguard Worker 
286*61046927SAndroid Build Coastguard Worker #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
287*61046927SAndroid Build Coastguard Worker    __glxHashDestroy(priv->drawHash);
288*61046927SAndroid Build Coastguard Worker    if (priv->dri2Hash)
289*61046927SAndroid Build Coastguard Worker       __glxHashDestroy(priv->dri2Hash);
290*61046927SAndroid Build Coastguard Worker 
291*61046927SAndroid Build Coastguard Worker #endif /* GLX_DIRECT_RENDERING && !GLX_USE_APPLEGL */
292*61046927SAndroid Build Coastguard Worker 
293*61046927SAndroid Build Coastguard Worker    free((char *) priv);
294*61046927SAndroid Build Coastguard Worker }
295*61046927SAndroid Build Coastguard Worker 
296*61046927SAndroid Build Coastguard Worker static int
__glXCloseDisplay(Display * dpy,XExtCodes * codes)297*61046927SAndroid Build Coastguard Worker __glXCloseDisplay(Display * dpy, XExtCodes * codes)
298*61046927SAndroid Build Coastguard Worker {
299*61046927SAndroid Build Coastguard Worker    struct glx_display *priv, **prev;
300*61046927SAndroid Build Coastguard Worker 
301*61046927SAndroid Build Coastguard Worker    _XLockMutex(_Xglobal_lock);
302*61046927SAndroid Build Coastguard Worker    prev = &glx_displays;
303*61046927SAndroid Build Coastguard Worker    for (priv = glx_displays; priv; prev = &priv->next, priv = priv->next) {
304*61046927SAndroid Build Coastguard Worker       if (priv->dpy == dpy) {
305*61046927SAndroid Build Coastguard Worker          *prev = priv->next;
306*61046927SAndroid Build Coastguard Worker 	 break;
307*61046927SAndroid Build Coastguard Worker       }
308*61046927SAndroid Build Coastguard Worker    }
309*61046927SAndroid Build Coastguard Worker    _XUnlockMutex(_Xglobal_lock);
310*61046927SAndroid Build Coastguard Worker 
311*61046927SAndroid Build Coastguard Worker    if (priv != NULL)
312*61046927SAndroid Build Coastguard Worker       glx_display_free(priv);
313*61046927SAndroid Build Coastguard Worker 
314*61046927SAndroid Build Coastguard Worker    return 1;
315*61046927SAndroid Build Coastguard Worker }
316*61046927SAndroid Build Coastguard Worker 
317*61046927SAndroid Build Coastguard Worker /*
318*61046927SAndroid Build Coastguard Worker ** Query the version of the GLX extension.  This procedure works even if
319*61046927SAndroid Build Coastguard Worker ** the client extension is not completely set up.
320*61046927SAndroid Build Coastguard Worker */
321*61046927SAndroid Build Coastguard Worker static Bool
QueryVersion(Display * dpy,int opcode,int * major,int * minor)322*61046927SAndroid Build Coastguard Worker QueryVersion(Display * dpy, int opcode, int *major, int *minor)
323*61046927SAndroid Build Coastguard Worker {
324*61046927SAndroid Build Coastguard Worker    xcb_connection_t *c = XGetXCBConnection(dpy);
325*61046927SAndroid Build Coastguard Worker    xcb_glx_query_version_reply_t *reply = xcb_glx_query_version_reply(c,
326*61046927SAndroid Build Coastguard Worker                                                                       xcb_glx_query_version
327*61046927SAndroid Build Coastguard Worker                                                                       (c,
328*61046927SAndroid Build Coastguard Worker                                                                        GLX_MAJOR_VERSION,
329*61046927SAndroid Build Coastguard Worker                                                                        GLX_MINOR_VERSION),
330*61046927SAndroid Build Coastguard Worker                                                                       NULL);
331*61046927SAndroid Build Coastguard Worker 
332*61046927SAndroid Build Coastguard Worker    if (!reply)
333*61046927SAndroid Build Coastguard Worker      return GL_FALSE;
334*61046927SAndroid Build Coastguard Worker 
335*61046927SAndroid Build Coastguard Worker    if (reply->major_version != GLX_MAJOR_VERSION) {
336*61046927SAndroid Build Coastguard Worker       free(reply);
337*61046927SAndroid Build Coastguard Worker       return GL_FALSE;
338*61046927SAndroid Build Coastguard Worker    }
339*61046927SAndroid Build Coastguard Worker    *major = reply->major_version;
340*61046927SAndroid Build Coastguard Worker    *minor = min(reply->minor_version, GLX_MINOR_VERSION);
341*61046927SAndroid Build Coastguard Worker    free(reply);
342*61046927SAndroid Build Coastguard Worker    return GL_TRUE;
343*61046927SAndroid Build Coastguard Worker }
344*61046927SAndroid Build Coastguard Worker 
345*61046927SAndroid Build Coastguard Worker /*
346*61046927SAndroid Build Coastguard Worker  * We don't want to enable this GLX_OML_swap_method in glxext.h,
347*61046927SAndroid Build Coastguard Worker  * because we can't support it.  The X server writes it out though,
348*61046927SAndroid Build Coastguard Worker  * so we should handle it somehow, to avoid false warnings.
349*61046927SAndroid Build Coastguard Worker  */
350*61046927SAndroid Build Coastguard Worker enum {
351*61046927SAndroid Build Coastguard Worker     IGNORE_GLX_SWAP_METHOD_OML = 0x8060
352*61046927SAndroid Build Coastguard Worker };
353*61046927SAndroid Build Coastguard Worker 
354*61046927SAndroid Build Coastguard Worker 
355*61046927SAndroid Build Coastguard Worker static GLint
convert_from_x_visual_type(int visualType)356*61046927SAndroid Build Coastguard Worker convert_from_x_visual_type(int visualType)
357*61046927SAndroid Build Coastguard Worker {
358*61046927SAndroid Build Coastguard Worker    static const int glx_visual_types[] = {
359*61046927SAndroid Build Coastguard Worker       [StaticGray]  = GLX_STATIC_GRAY,
360*61046927SAndroid Build Coastguard Worker       [GrayScale]   = GLX_GRAY_SCALE,
361*61046927SAndroid Build Coastguard Worker       [StaticColor] = GLX_STATIC_COLOR,
362*61046927SAndroid Build Coastguard Worker       [PseudoColor] = GLX_PSEUDO_COLOR,
363*61046927SAndroid Build Coastguard Worker       [TrueColor]   = GLX_TRUE_COLOR,
364*61046927SAndroid Build Coastguard Worker       [DirectColor] = GLX_DIRECT_COLOR,
365*61046927SAndroid Build Coastguard Worker    };
366*61046927SAndroid Build Coastguard Worker 
367*61046927SAndroid Build Coastguard Worker    if (visualType < ARRAY_SIZE(glx_visual_types))
368*61046927SAndroid Build Coastguard Worker       return glx_visual_types[visualType];
369*61046927SAndroid Build Coastguard Worker 
370*61046927SAndroid Build Coastguard Worker    return GLX_NONE;
371*61046927SAndroid Build Coastguard Worker }
372*61046927SAndroid Build Coastguard Worker 
373*61046927SAndroid Build Coastguard Worker /*
374*61046927SAndroid Build Coastguard Worker  * getVisualConfigs uses the !tagged_only path.
375*61046927SAndroid Build Coastguard Worker  * getFBConfigs uses the tagged_only path.
376*61046927SAndroid Build Coastguard Worker  */
377*61046927SAndroid Build Coastguard Worker _X_HIDDEN void
__glXInitializeVisualConfigFromTags(struct glx_config * config,int count,const INT32 * bp,Bool tagged_only,Bool fbconfig_style_tags)378*61046927SAndroid Build Coastguard Worker __glXInitializeVisualConfigFromTags(struct glx_config * config, int count,
379*61046927SAndroid Build Coastguard Worker                                     const INT32 * bp, Bool tagged_only,
380*61046927SAndroid Build Coastguard Worker                                     Bool fbconfig_style_tags)
381*61046927SAndroid Build Coastguard Worker {
382*61046927SAndroid Build Coastguard Worker    int i;
383*61046927SAndroid Build Coastguard Worker 
384*61046927SAndroid Build Coastguard Worker    if (!tagged_only) {
385*61046927SAndroid Build Coastguard Worker       /* Copy in the first set of properties */
386*61046927SAndroid Build Coastguard Worker       config->visualID = *bp++;
387*61046927SAndroid Build Coastguard Worker 
388*61046927SAndroid Build Coastguard Worker       config->visualType = convert_from_x_visual_type(*bp++);
389*61046927SAndroid Build Coastguard Worker 
390*61046927SAndroid Build Coastguard Worker       config->renderType = *bp++ ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
391*61046927SAndroid Build Coastguard Worker 
392*61046927SAndroid Build Coastguard Worker       config->redBits = *bp++;
393*61046927SAndroid Build Coastguard Worker       config->greenBits = *bp++;
394*61046927SAndroid Build Coastguard Worker       config->blueBits = *bp++;
395*61046927SAndroid Build Coastguard Worker       config->alphaBits = *bp++;
396*61046927SAndroid Build Coastguard Worker       config->accumRedBits = *bp++;
397*61046927SAndroid Build Coastguard Worker       config->accumGreenBits = *bp++;
398*61046927SAndroid Build Coastguard Worker       config->accumBlueBits = *bp++;
399*61046927SAndroid Build Coastguard Worker       config->accumAlphaBits = *bp++;
400*61046927SAndroid Build Coastguard Worker 
401*61046927SAndroid Build Coastguard Worker       config->doubleBufferMode = *bp++;
402*61046927SAndroid Build Coastguard Worker       config->stereoMode = *bp++;
403*61046927SAndroid Build Coastguard Worker 
404*61046927SAndroid Build Coastguard Worker       config->rgbBits = *bp++;
405*61046927SAndroid Build Coastguard Worker       config->depthBits = *bp++;
406*61046927SAndroid Build Coastguard Worker       config->stencilBits = *bp++;
407*61046927SAndroid Build Coastguard Worker       config->numAuxBuffers = *bp++;
408*61046927SAndroid Build Coastguard Worker       config->level = *bp++;
409*61046927SAndroid Build Coastguard Worker 
410*61046927SAndroid Build Coastguard Worker #ifdef GLX_USE_APPLEGL
411*61046927SAndroid Build Coastguard Worker        /* AppleSGLX supports pixmap and pbuffers with all config. */
412*61046927SAndroid Build Coastguard Worker        config->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
413*61046927SAndroid Build Coastguard Worker        /* Unfortunately this can create an ABI compatibility problem. */
414*61046927SAndroid Build Coastguard Worker        count -= 18;
415*61046927SAndroid Build Coastguard Worker #else
416*61046927SAndroid Build Coastguard Worker       count -= __GLX_MIN_CONFIG_PROPS;
417*61046927SAndroid Build Coastguard Worker #endif
418*61046927SAndroid Build Coastguard Worker    }
419*61046927SAndroid Build Coastguard Worker 
420*61046927SAndroid Build Coastguard Worker    /*
421*61046927SAndroid Build Coastguard Worker     ** Additional properties may be in a list at the end
422*61046927SAndroid Build Coastguard Worker     ** of the reply.  They are in pairs of property type
423*61046927SAndroid Build Coastguard Worker     ** and property value.
424*61046927SAndroid Build Coastguard Worker     */
425*61046927SAndroid Build Coastguard Worker 
426*61046927SAndroid Build Coastguard Worker #define FETCH_OR_SET(tag) \
427*61046927SAndroid Build Coastguard Worker     config-> tag = ( fbconfig_style_tags ) ? *bp++ : 1
428*61046927SAndroid Build Coastguard Worker 
429*61046927SAndroid Build Coastguard Worker    for (i = 0; i < count; i += 2) {
430*61046927SAndroid Build Coastguard Worker       long int tag = *bp++;
431*61046927SAndroid Build Coastguard Worker 
432*61046927SAndroid Build Coastguard Worker       switch (tag) {
433*61046927SAndroid Build Coastguard Worker       case GLX_RGBA:
434*61046927SAndroid Build Coastguard Worker          if (fbconfig_style_tags)
435*61046927SAndroid Build Coastguard Worker             config->renderType = *bp++ ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
436*61046927SAndroid Build Coastguard Worker          else
437*61046927SAndroid Build Coastguard Worker             config->renderType = GLX_RGBA_BIT;
438*61046927SAndroid Build Coastguard Worker          break;
439*61046927SAndroid Build Coastguard Worker       case GLX_BUFFER_SIZE:
440*61046927SAndroid Build Coastguard Worker          config->rgbBits = *bp++;
441*61046927SAndroid Build Coastguard Worker          break;
442*61046927SAndroid Build Coastguard Worker       case GLX_LEVEL:
443*61046927SAndroid Build Coastguard Worker          config->level = *bp++;
444*61046927SAndroid Build Coastguard Worker          break;
445*61046927SAndroid Build Coastguard Worker       case GLX_DOUBLEBUFFER:
446*61046927SAndroid Build Coastguard Worker          FETCH_OR_SET(doubleBufferMode);
447*61046927SAndroid Build Coastguard Worker          break;
448*61046927SAndroid Build Coastguard Worker       case GLX_STEREO:
449*61046927SAndroid Build Coastguard Worker          FETCH_OR_SET(stereoMode);
450*61046927SAndroid Build Coastguard Worker          break;
451*61046927SAndroid Build Coastguard Worker       case GLX_AUX_BUFFERS:
452*61046927SAndroid Build Coastguard Worker          config->numAuxBuffers = *bp++;
453*61046927SAndroid Build Coastguard Worker          break;
454*61046927SAndroid Build Coastguard Worker       case GLX_RED_SIZE:
455*61046927SAndroid Build Coastguard Worker          config->redBits = *bp++;
456*61046927SAndroid Build Coastguard Worker          break;
457*61046927SAndroid Build Coastguard Worker       case GLX_GREEN_SIZE:
458*61046927SAndroid Build Coastguard Worker          config->greenBits = *bp++;
459*61046927SAndroid Build Coastguard Worker          break;
460*61046927SAndroid Build Coastguard Worker       case GLX_BLUE_SIZE:
461*61046927SAndroid Build Coastguard Worker          config->blueBits = *bp++;
462*61046927SAndroid Build Coastguard Worker          break;
463*61046927SAndroid Build Coastguard Worker       case GLX_ALPHA_SIZE:
464*61046927SAndroid Build Coastguard Worker          config->alphaBits = *bp++;
465*61046927SAndroid Build Coastguard Worker          break;
466*61046927SAndroid Build Coastguard Worker       case GLX_DEPTH_SIZE:
467*61046927SAndroid Build Coastguard Worker          config->depthBits = *bp++;
468*61046927SAndroid Build Coastguard Worker          break;
469*61046927SAndroid Build Coastguard Worker       case GLX_STENCIL_SIZE:
470*61046927SAndroid Build Coastguard Worker          config->stencilBits = *bp++;
471*61046927SAndroid Build Coastguard Worker          break;
472*61046927SAndroid Build Coastguard Worker       case GLX_ACCUM_RED_SIZE:
473*61046927SAndroid Build Coastguard Worker          config->accumRedBits = *bp++;
474*61046927SAndroid Build Coastguard Worker          break;
475*61046927SAndroid Build Coastguard Worker       case GLX_ACCUM_GREEN_SIZE:
476*61046927SAndroid Build Coastguard Worker          config->accumGreenBits = *bp++;
477*61046927SAndroid Build Coastguard Worker          break;
478*61046927SAndroid Build Coastguard Worker       case GLX_ACCUM_BLUE_SIZE:
479*61046927SAndroid Build Coastguard Worker          config->accumBlueBits = *bp++;
480*61046927SAndroid Build Coastguard Worker          break;
481*61046927SAndroid Build Coastguard Worker       case GLX_ACCUM_ALPHA_SIZE:
482*61046927SAndroid Build Coastguard Worker          config->accumAlphaBits = *bp++;
483*61046927SAndroid Build Coastguard Worker          break;
484*61046927SAndroid Build Coastguard Worker       case GLX_VISUAL_CAVEAT_EXT:
485*61046927SAndroid Build Coastguard Worker          config->visualRating = *bp++;
486*61046927SAndroid Build Coastguard Worker          break;
487*61046927SAndroid Build Coastguard Worker       case GLX_X_VISUAL_TYPE:
488*61046927SAndroid Build Coastguard Worker          config->visualType = *bp++;
489*61046927SAndroid Build Coastguard Worker          break;
490*61046927SAndroid Build Coastguard Worker       case GLX_TRANSPARENT_TYPE:
491*61046927SAndroid Build Coastguard Worker          config->transparentPixel = *bp++;
492*61046927SAndroid Build Coastguard Worker          break;
493*61046927SAndroid Build Coastguard Worker       case GLX_TRANSPARENT_INDEX_VALUE:
494*61046927SAndroid Build Coastguard Worker          config->transparentIndex = *bp++;
495*61046927SAndroid Build Coastguard Worker          break;
496*61046927SAndroid Build Coastguard Worker       case GLX_TRANSPARENT_RED_VALUE:
497*61046927SAndroid Build Coastguard Worker          config->transparentRed = *bp++;
498*61046927SAndroid Build Coastguard Worker          break;
499*61046927SAndroid Build Coastguard Worker       case GLX_TRANSPARENT_GREEN_VALUE:
500*61046927SAndroid Build Coastguard Worker          config->transparentGreen = *bp++;
501*61046927SAndroid Build Coastguard Worker          break;
502*61046927SAndroid Build Coastguard Worker       case GLX_TRANSPARENT_BLUE_VALUE:
503*61046927SAndroid Build Coastguard Worker          config->transparentBlue = *bp++;
504*61046927SAndroid Build Coastguard Worker          break;
505*61046927SAndroid Build Coastguard Worker       case GLX_TRANSPARENT_ALPHA_VALUE:
506*61046927SAndroid Build Coastguard Worker          config->transparentAlpha = *bp++;
507*61046927SAndroid Build Coastguard Worker          break;
508*61046927SAndroid Build Coastguard Worker       case GLX_VISUAL_ID:
509*61046927SAndroid Build Coastguard Worker          config->visualID = *bp++;
510*61046927SAndroid Build Coastguard Worker          break;
511*61046927SAndroid Build Coastguard Worker       case GLX_DRAWABLE_TYPE:
512*61046927SAndroid Build Coastguard Worker          config->drawableType = *bp++;
513*61046927SAndroid Build Coastguard Worker #ifdef GLX_USE_APPLEGL
514*61046927SAndroid Build Coastguard Worker          /* AppleSGLX supports pixmap and pbuffers with all config. */
515*61046927SAndroid Build Coastguard Worker          config->drawableType |= GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
516*61046927SAndroid Build Coastguard Worker #endif
517*61046927SAndroid Build Coastguard Worker          break;
518*61046927SAndroid Build Coastguard Worker       case GLX_RENDER_TYPE: /* fbconfig render type bits */
519*61046927SAndroid Build Coastguard Worker          config->renderType = *bp++;
520*61046927SAndroid Build Coastguard Worker          break;
521*61046927SAndroid Build Coastguard Worker       case GLX_X_RENDERABLE:
522*61046927SAndroid Build Coastguard Worker          config->xRenderable = *bp++;
523*61046927SAndroid Build Coastguard Worker          break;
524*61046927SAndroid Build Coastguard Worker       case GLX_FBCONFIG_ID:
525*61046927SAndroid Build Coastguard Worker          config->fbconfigID = *bp++;
526*61046927SAndroid Build Coastguard Worker          break;
527*61046927SAndroid Build Coastguard Worker       case GLX_MAX_PBUFFER_WIDTH:
528*61046927SAndroid Build Coastguard Worker          config->maxPbufferWidth = *bp++;
529*61046927SAndroid Build Coastguard Worker          break;
530*61046927SAndroid Build Coastguard Worker       case GLX_MAX_PBUFFER_HEIGHT:
531*61046927SAndroid Build Coastguard Worker          config->maxPbufferHeight = *bp++;
532*61046927SAndroid Build Coastguard Worker          break;
533*61046927SAndroid Build Coastguard Worker       case GLX_MAX_PBUFFER_PIXELS:
534*61046927SAndroid Build Coastguard Worker          config->maxPbufferPixels = *bp++;
535*61046927SAndroid Build Coastguard Worker          break;
536*61046927SAndroid Build Coastguard Worker #ifndef GLX_USE_APPLEGL
537*61046927SAndroid Build Coastguard Worker       case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX:
538*61046927SAndroid Build Coastguard Worker          config->optimalPbufferWidth = *bp++;
539*61046927SAndroid Build Coastguard Worker          break;
540*61046927SAndroid Build Coastguard Worker       case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX:
541*61046927SAndroid Build Coastguard Worker          config->optimalPbufferHeight = *bp++;
542*61046927SAndroid Build Coastguard Worker          break;
543*61046927SAndroid Build Coastguard Worker       case GLX_VISUAL_SELECT_GROUP_SGIX:
544*61046927SAndroid Build Coastguard Worker          config->visualSelectGroup = *bp++;
545*61046927SAndroid Build Coastguard Worker          break;
546*61046927SAndroid Build Coastguard Worker #endif
547*61046927SAndroid Build Coastguard Worker       case GLX_SAMPLE_BUFFERS_SGIS:
548*61046927SAndroid Build Coastguard Worker          config->sampleBuffers = *bp++;
549*61046927SAndroid Build Coastguard Worker          break;
550*61046927SAndroid Build Coastguard Worker       case GLX_SAMPLES_SGIS:
551*61046927SAndroid Build Coastguard Worker          config->samples = *bp++;
552*61046927SAndroid Build Coastguard Worker          break;
553*61046927SAndroid Build Coastguard Worker       case IGNORE_GLX_SWAP_METHOD_OML:
554*61046927SAndroid Build Coastguard Worker          /* We ignore this tag.  See the comment above this function. */
555*61046927SAndroid Build Coastguard Worker          ++bp;
556*61046927SAndroid Build Coastguard Worker          break;
557*61046927SAndroid Build Coastguard Worker #ifndef GLX_USE_APPLEGL
558*61046927SAndroid Build Coastguard Worker       case GLX_BIND_TO_TEXTURE_RGB_EXT:
559*61046927SAndroid Build Coastguard Worker          config->bindToTextureRgb = *bp++;
560*61046927SAndroid Build Coastguard Worker          break;
561*61046927SAndroid Build Coastguard Worker       case GLX_BIND_TO_TEXTURE_RGBA_EXT:
562*61046927SAndroid Build Coastguard Worker          config->bindToTextureRgba = *bp++;
563*61046927SAndroid Build Coastguard Worker          break;
564*61046927SAndroid Build Coastguard Worker       case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
565*61046927SAndroid Build Coastguard Worker          config->bindToMipmapTexture = *bp++;
566*61046927SAndroid Build Coastguard Worker          break;
567*61046927SAndroid Build Coastguard Worker       case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
568*61046927SAndroid Build Coastguard Worker          config->bindToTextureTargets = *bp++;
569*61046927SAndroid Build Coastguard Worker          break;
570*61046927SAndroid Build Coastguard Worker       case GLX_Y_INVERTED_EXT:
571*61046927SAndroid Build Coastguard Worker          config->yInverted = *bp++;
572*61046927SAndroid Build Coastguard Worker          break;
573*61046927SAndroid Build Coastguard Worker #endif
574*61046927SAndroid Build Coastguard Worker       case GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT:
575*61046927SAndroid Build Coastguard Worker          config->sRGBCapable = *bp++;
576*61046927SAndroid Build Coastguard Worker          break;
577*61046927SAndroid Build Coastguard Worker 
578*61046927SAndroid Build Coastguard Worker       case GLX_USE_GL:
579*61046927SAndroid Build Coastguard Worker          if (fbconfig_style_tags)
580*61046927SAndroid Build Coastguard Worker             bp++;
581*61046927SAndroid Build Coastguard Worker          break;
582*61046927SAndroid Build Coastguard Worker       case GLX_FLOAT_COMPONENTS_NV:
583*61046927SAndroid Build Coastguard Worker          config->floatComponentsNV = *bp++;
584*61046927SAndroid Build Coastguard Worker          break;
585*61046927SAndroid Build Coastguard Worker       case None:
586*61046927SAndroid Build Coastguard Worker          i = count;
587*61046927SAndroid Build Coastguard Worker          break;
588*61046927SAndroid Build Coastguard Worker       default: {
589*61046927SAndroid Build Coastguard Worker             long int tagvalue = *bp++;
590*61046927SAndroid Build Coastguard Worker             DebugMessageF("WARNING: unknown fbconfig attribute from server: "
591*61046927SAndroid Build Coastguard Worker                           "tag 0x%lx value 0x%lx\n", tag, tagvalue);
592*61046927SAndroid Build Coastguard Worker             break;
593*61046927SAndroid Build Coastguard Worker          }
594*61046927SAndroid Build Coastguard Worker       }
595*61046927SAndroid Build Coastguard Worker    }
596*61046927SAndroid Build Coastguard Worker }
597*61046927SAndroid Build Coastguard Worker 
598*61046927SAndroid Build Coastguard Worker static struct glx_config *
createConfigsFromProperties(Display * dpy,int nvisuals,int nprops,int screen,GLboolean tagged_only)599*61046927SAndroid Build Coastguard Worker createConfigsFromProperties(Display * dpy, int nvisuals, int nprops,
600*61046927SAndroid Build Coastguard Worker                             int screen, GLboolean tagged_only)
601*61046927SAndroid Build Coastguard Worker {
602*61046927SAndroid Build Coastguard Worker    INT32 buf[__GLX_TOTAL_CONFIG], *props;
603*61046927SAndroid Build Coastguard Worker    unsigned prop_size;
604*61046927SAndroid Build Coastguard Worker    struct glx_config *modes, *m;
605*61046927SAndroid Build Coastguard Worker    int i;
606*61046927SAndroid Build Coastguard Worker 
607*61046927SAndroid Build Coastguard Worker    if (nprops == 0)
608*61046927SAndroid Build Coastguard Worker       return NULL;
609*61046927SAndroid Build Coastguard Worker 
610*61046927SAndroid Build Coastguard Worker    /* Check number of properties */
611*61046927SAndroid Build Coastguard Worker    if (nprops < __GLX_MIN_CONFIG_PROPS)
612*61046927SAndroid Build Coastguard Worker       return NULL;
613*61046927SAndroid Build Coastguard Worker 
614*61046927SAndroid Build Coastguard Worker    /* Allocate memory for our config structure */
615*61046927SAndroid Build Coastguard Worker    modes = glx_config_create_list(nvisuals);
616*61046927SAndroid Build Coastguard Worker    if (!modes)
617*61046927SAndroid Build Coastguard Worker       return NULL;
618*61046927SAndroid Build Coastguard Worker 
619*61046927SAndroid Build Coastguard Worker    prop_size = nprops * __GLX_SIZE_INT32;
620*61046927SAndroid Build Coastguard Worker    if (prop_size <= sizeof(buf))
621*61046927SAndroid Build Coastguard Worker       props = buf;
622*61046927SAndroid Build Coastguard Worker    else
623*61046927SAndroid Build Coastguard Worker       props = malloc(prop_size);
624*61046927SAndroid Build Coastguard Worker 
625*61046927SAndroid Build Coastguard Worker    /* Read each config structure and convert it into our format */
626*61046927SAndroid Build Coastguard Worker    m = modes;
627*61046927SAndroid Build Coastguard Worker    for (i = 0; i < nvisuals; i++) {
628*61046927SAndroid Build Coastguard Worker       _XRead(dpy, (char *) props, prop_size);
629*61046927SAndroid Build Coastguard Worker       /* If this is GLXGetVisualConfigs then the reply will not include
630*61046927SAndroid Build Coastguard Worker        * any drawable type info, but window support is implied because
631*61046927SAndroid Build Coastguard Worker        * that's what a Visual describes, and pixmap support is implied
632*61046927SAndroid Build Coastguard Worker        * because you almost certainly have a pixmap format corresponding
633*61046927SAndroid Build Coastguard Worker        * to your visual format.
634*61046927SAndroid Build Coastguard Worker        */
635*61046927SAndroid Build Coastguard Worker       if (!tagged_only)
636*61046927SAndroid Build Coastguard Worker          m->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT;
637*61046927SAndroid Build Coastguard Worker       __glXInitializeVisualConfigFromTags(m, nprops, props,
638*61046927SAndroid Build Coastguard Worker                                           tagged_only, GL_TRUE);
639*61046927SAndroid Build Coastguard Worker       m->screen = screen;
640*61046927SAndroid Build Coastguard Worker       m = m->next;
641*61046927SAndroid Build Coastguard Worker    }
642*61046927SAndroid Build Coastguard Worker 
643*61046927SAndroid Build Coastguard Worker    if (props != buf)
644*61046927SAndroid Build Coastguard Worker       free(props);
645*61046927SAndroid Build Coastguard Worker 
646*61046927SAndroid Build Coastguard Worker    return modes;
647*61046927SAndroid Build Coastguard Worker }
648*61046927SAndroid Build Coastguard Worker 
649*61046927SAndroid Build Coastguard Worker static GLboolean
getVisualConfigs(struct glx_screen * psc,struct glx_display * priv,int screen)650*61046927SAndroid Build Coastguard Worker getVisualConfigs(struct glx_screen *psc,
651*61046927SAndroid Build Coastguard Worker 		  struct glx_display *priv, int screen)
652*61046927SAndroid Build Coastguard Worker {
653*61046927SAndroid Build Coastguard Worker    xGLXGetVisualConfigsReq *req;
654*61046927SAndroid Build Coastguard Worker    xGLXGetVisualConfigsReply reply;
655*61046927SAndroid Build Coastguard Worker    Display *dpy = priv->dpy;
656*61046927SAndroid Build Coastguard Worker 
657*61046927SAndroid Build Coastguard Worker    LockDisplay(dpy);
658*61046927SAndroid Build Coastguard Worker 
659*61046927SAndroid Build Coastguard Worker    psc->visuals = NULL;
660*61046927SAndroid Build Coastguard Worker    GetReq(GLXGetVisualConfigs, req);
661*61046927SAndroid Build Coastguard Worker    req->reqType = priv->codes.major_opcode;
662*61046927SAndroid Build Coastguard Worker    req->glxCode = X_GLXGetVisualConfigs;
663*61046927SAndroid Build Coastguard Worker    req->screen = screen;
664*61046927SAndroid Build Coastguard Worker 
665*61046927SAndroid Build Coastguard Worker    if (!_XReply(dpy, (xReply *) & reply, 0, False))
666*61046927SAndroid Build Coastguard Worker       goto out;
667*61046927SAndroid Build Coastguard Worker 
668*61046927SAndroid Build Coastguard Worker    psc->visuals = createConfigsFromProperties(dpy,
669*61046927SAndroid Build Coastguard Worker                                               reply.numVisuals,
670*61046927SAndroid Build Coastguard Worker                                               reply.numProps,
671*61046927SAndroid Build Coastguard Worker                                               screen, GL_FALSE);
672*61046927SAndroid Build Coastguard Worker 
673*61046927SAndroid Build Coastguard Worker  out:
674*61046927SAndroid Build Coastguard Worker    UnlockDisplay(dpy);
675*61046927SAndroid Build Coastguard Worker    return psc->visuals != NULL;
676*61046927SAndroid Build Coastguard Worker }
677*61046927SAndroid Build Coastguard Worker 
678*61046927SAndroid Build Coastguard Worker static GLboolean
getFBConfigs(struct glx_screen * psc,struct glx_display * priv,int screen)679*61046927SAndroid Build Coastguard Worker getFBConfigs(struct glx_screen *psc, struct glx_display *priv, int screen)
680*61046927SAndroid Build Coastguard Worker {
681*61046927SAndroid Build Coastguard Worker    xGLXGetFBConfigsReq *fb_req;
682*61046927SAndroid Build Coastguard Worker    xGLXGetFBConfigsReply reply;
683*61046927SAndroid Build Coastguard Worker    Display *dpy = priv->dpy;
684*61046927SAndroid Build Coastguard Worker 
685*61046927SAndroid Build Coastguard Worker    psc->serverGLXexts = __glXQueryServerString(dpy, screen, GLX_EXTENSIONS);
686*61046927SAndroid Build Coastguard Worker 
687*61046927SAndroid Build Coastguard Worker    if (psc->serverGLXexts == NULL) {
688*61046927SAndroid Build Coastguard Worker       return GL_FALSE;
689*61046927SAndroid Build Coastguard Worker    }
690*61046927SAndroid Build Coastguard Worker 
691*61046927SAndroid Build Coastguard Worker    LockDisplay(dpy);
692*61046927SAndroid Build Coastguard Worker 
693*61046927SAndroid Build Coastguard Worker    psc->configs = NULL;
694*61046927SAndroid Build Coastguard Worker    GetReq(GLXGetFBConfigs, fb_req);
695*61046927SAndroid Build Coastguard Worker    fb_req->reqType = priv->codes.major_opcode;
696*61046927SAndroid Build Coastguard Worker    fb_req->glxCode = X_GLXGetFBConfigs;
697*61046927SAndroid Build Coastguard Worker    fb_req->screen = screen;
698*61046927SAndroid Build Coastguard Worker 
699*61046927SAndroid Build Coastguard Worker    if (!_XReply(dpy, (xReply *) & reply, 0, False))
700*61046927SAndroid Build Coastguard Worker       goto out;
701*61046927SAndroid Build Coastguard Worker 
702*61046927SAndroid Build Coastguard Worker    psc->configs = createConfigsFromProperties(dpy,
703*61046927SAndroid Build Coastguard Worker                                               reply.numFBConfigs,
704*61046927SAndroid Build Coastguard Worker                                               reply.numAttribs * 2,
705*61046927SAndroid Build Coastguard Worker                                               screen, GL_TRUE);
706*61046927SAndroid Build Coastguard Worker 
707*61046927SAndroid Build Coastguard Worker  out:
708*61046927SAndroid Build Coastguard Worker    UnlockDisplay(dpy);
709*61046927SAndroid Build Coastguard Worker    return psc->configs != NULL;
710*61046927SAndroid Build Coastguard Worker }
711*61046927SAndroid Build Coastguard Worker 
712*61046927SAndroid Build Coastguard Worker _X_HIDDEN Bool
glx_screen_init(struct glx_screen * psc,int screen,struct glx_display * priv)713*61046927SAndroid Build Coastguard Worker glx_screen_init(struct glx_screen *psc,
714*61046927SAndroid Build Coastguard Worker 		 int screen, struct glx_display * priv)
715*61046927SAndroid Build Coastguard Worker {
716*61046927SAndroid Build Coastguard Worker    /* Initialize per screen dynamic client GLX extensions */
717*61046927SAndroid Build Coastguard Worker    psc->ext_list_first_time = GL_TRUE;
718*61046927SAndroid Build Coastguard Worker    psc->scr = screen;
719*61046927SAndroid Build Coastguard Worker    psc->dpy = priv->dpy;
720*61046927SAndroid Build Coastguard Worker    psc->display = priv;
721*61046927SAndroid Build Coastguard Worker 
722*61046927SAndroid Build Coastguard Worker    if (!getVisualConfigs(psc, priv, screen))
723*61046927SAndroid Build Coastguard Worker       return GL_FALSE;
724*61046927SAndroid Build Coastguard Worker 
725*61046927SAndroid Build Coastguard Worker    if (!getFBConfigs(psc, priv, screen))
726*61046927SAndroid Build Coastguard Worker       return GL_FALSE;
727*61046927SAndroid Build Coastguard Worker 
728*61046927SAndroid Build Coastguard Worker    return GL_TRUE;
729*61046927SAndroid Build Coastguard Worker }
730*61046927SAndroid Build Coastguard Worker 
731*61046927SAndroid Build Coastguard Worker _X_HIDDEN void
glx_screen_cleanup(struct glx_screen * psc)732*61046927SAndroid Build Coastguard Worker glx_screen_cleanup(struct glx_screen *psc)
733*61046927SAndroid Build Coastguard Worker {
734*61046927SAndroid Build Coastguard Worker    if (psc->configs) {
735*61046927SAndroid Build Coastguard Worker       glx_config_destroy_list(psc->configs);
736*61046927SAndroid Build Coastguard Worker       free(psc->effectiveGLXexts);
737*61046927SAndroid Build Coastguard Worker       psc->configs = NULL;   /* NOTE: just for paranoia */
738*61046927SAndroid Build Coastguard Worker    }
739*61046927SAndroid Build Coastguard Worker    if (psc->visuals) {
740*61046927SAndroid Build Coastguard Worker       glx_config_destroy_list(psc->visuals);
741*61046927SAndroid Build Coastguard Worker       psc->visuals = NULL;   /* NOTE: just for paranoia */
742*61046927SAndroid Build Coastguard Worker    }
743*61046927SAndroid Build Coastguard Worker #if defined(GLX_DIRECT_RENDERING) && (!defined(GLX_USE_APPLEGL) || defined(GLX_USE_APPLE))
744*61046927SAndroid Build Coastguard Worker    if (psc->driver_configs) {
745*61046927SAndroid Build Coastguard Worker       driDestroyConfigs(psc->driver_configs);
746*61046927SAndroid Build Coastguard Worker       psc->driver_configs = NULL;
747*61046927SAndroid Build Coastguard Worker    }
748*61046927SAndroid Build Coastguard Worker #endif
749*61046927SAndroid Build Coastguard Worker    free((char *) psc->serverGLXexts);
750*61046927SAndroid Build Coastguard Worker    free((char *) psc->serverGLXvendor);
751*61046927SAndroid Build Coastguard Worker    free((char *) psc->serverGLXversion);
752*61046927SAndroid Build Coastguard Worker    free(psc->driverName);
753*61046927SAndroid Build Coastguard Worker }
754*61046927SAndroid Build Coastguard Worker 
755*61046927SAndroid Build Coastguard Worker static void
bind_extensions(struct glx_screen * psc,const char * driverName)756*61046927SAndroid Build Coastguard Worker bind_extensions(struct glx_screen *psc, const char *driverName)
757*61046927SAndroid Build Coastguard Worker {
758*61046927SAndroid Build Coastguard Worker    unsigned mask;
759*61046927SAndroid Build Coastguard Worker 
760*61046927SAndroid Build Coastguard Worker    if (psc->display->driver != GLX_DRIVER_SW) {
761*61046927SAndroid Build Coastguard Worker       __glXEnableDirectExtension(psc, "GLX_EXT_buffer_age");
762*61046927SAndroid Build Coastguard Worker       __glXEnableDirectExtension(psc, "GLX_EXT_swap_control");
763*61046927SAndroid Build Coastguard Worker       __glXEnableDirectExtension(psc, "GLX_SGI_swap_control");
764*61046927SAndroid Build Coastguard Worker       __glXEnableDirectExtension(psc, "GLX_MESA_swap_control");
765*61046927SAndroid Build Coastguard Worker       __glXEnableDirectExtension(psc, "GLX_OML_sync_control");
766*61046927SAndroid Build Coastguard Worker       __glXEnableDirectExtension(psc, "GLX_SGI_video_sync");
767*61046927SAndroid Build Coastguard Worker       // for zink this needs to check whether RELAXED is available
768*61046927SAndroid Build Coastguard Worker       if (psc->display->driver == GLX_DRIVER_DRI3)
769*61046927SAndroid Build Coastguard Worker          __glXEnableDirectExtension(psc, "GLX_EXT_swap_control_tear");
770*61046927SAndroid Build Coastguard Worker    }
771*61046927SAndroid Build Coastguard Worker    if (psc->display->driver != GLX_DRIVER_ZINK_YES)
772*61046927SAndroid Build Coastguard Worker       __glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer");
773*61046927SAndroid Build Coastguard Worker    __glXEnableDirectExtension(psc, "GLX_SGI_make_current_read");
774*61046927SAndroid Build Coastguard Worker 
775*61046927SAndroid Build Coastguard Worker    if (psc->can_EXT_texture_from_pixmap)
776*61046927SAndroid Build Coastguard Worker       __glXEnableDirectExtension(psc, "GLX_EXT_texture_from_pixmap");
777*61046927SAndroid Build Coastguard Worker 
778*61046927SAndroid Build Coastguard Worker    /*
779*61046927SAndroid Build Coastguard Worker     * GLX_INTEL_swap_event is broken on the server side, where it's
780*61046927SAndroid Build Coastguard Worker     * currently unconditionally enabled. This completely breaks
781*61046927SAndroid Build Coastguard Worker     * systems running on drivers which don't support that extension.
782*61046927SAndroid Build Coastguard Worker     * There's no way to test for its presence on this side, so instead
783*61046927SAndroid Build Coastguard Worker     * of disabling it unconditionally, just disable it for drivers
784*61046927SAndroid Build Coastguard Worker     * which are known to not support it.
785*61046927SAndroid Build Coastguard Worker     *
786*61046927SAndroid Build Coastguard Worker     * This was fixed in xserver 1.15.0 (190b03215), so now we only
787*61046927SAndroid Build Coastguard Worker     * disable the broken driver.
788*61046927SAndroid Build Coastguard Worker     */
789*61046927SAndroid Build Coastguard Worker    if (!driverName || strcmp(driverName, "vmwgfx") != 0) {
790*61046927SAndroid Build Coastguard Worker       __glXEnableDirectExtension(psc, "GLX_INTEL_swap_event");
791*61046927SAndroid Build Coastguard Worker    }
792*61046927SAndroid Build Coastguard Worker 
793*61046927SAndroid Build Coastguard Worker    mask = driGetAPIMask(psc->frontend_screen);
794*61046927SAndroid Build Coastguard Worker 
795*61046927SAndroid Build Coastguard Worker    __glXEnableDirectExtension(psc, "GLX_ARB_create_context");
796*61046927SAndroid Build Coastguard Worker    __glXEnableDirectExtension(psc, "GLX_ARB_create_context_profile");
797*61046927SAndroid Build Coastguard Worker    __glXEnableDirectExtension(psc, "GLX_ARB_create_context_no_error");
798*61046927SAndroid Build Coastguard Worker    __glXEnableDirectExtension(psc, "GLX_EXT_no_config_context");
799*61046927SAndroid Build Coastguard Worker 
800*61046927SAndroid Build Coastguard Worker    if ((mask & ((1 << __DRI_API_GLES) |
801*61046927SAndroid Build Coastguard Worker                 (1 << __DRI_API_GLES2) |
802*61046927SAndroid Build Coastguard Worker                 (1 << __DRI_API_GLES3))) != 0) {
803*61046927SAndroid Build Coastguard Worker       __glXEnableDirectExtension(psc,
804*61046927SAndroid Build Coastguard Worker                                  "GLX_EXT_create_context_es_profile");
805*61046927SAndroid Build Coastguard Worker       __glXEnableDirectExtension(psc,
806*61046927SAndroid Build Coastguard Worker                                  "GLX_EXT_create_context_es2_profile");
807*61046927SAndroid Build Coastguard Worker    }
808*61046927SAndroid Build Coastguard Worker 
809*61046927SAndroid Build Coastguard Worker    if (dri_get_screen_param(psc->frontend_screen, PIPE_CAP_DEVICE_RESET_STATUS_QUERY))
810*61046927SAndroid Build Coastguard Worker       __glXEnableDirectExtension(psc,
811*61046927SAndroid Build Coastguard Worker                                  "GLX_ARB_create_context_robustness");
812*61046927SAndroid Build Coastguard Worker 
813*61046927SAndroid Build Coastguard Worker    __glXEnableDirectExtension(psc, "GLX_ARB_context_flush_control");
814*61046927SAndroid Build Coastguard Worker    __glXEnableDirectExtension(psc, "GLX_MESA_query_renderer");
815*61046927SAndroid Build Coastguard Worker 
816*61046927SAndroid Build Coastguard Worker    __glXEnableDirectExtension(psc, "GLX_MESA_gl_interop");
817*61046927SAndroid Build Coastguard Worker 
818*61046927SAndroid Build Coastguard Worker    char *tmp;
819*61046927SAndroid Build Coastguard Worker    if (dri2GalliumConfigQuerys(psc->frontend_screen, "glx_extension_override",
820*61046927SAndroid Build Coastguard Worker                                     &tmp) == 0)
821*61046927SAndroid Build Coastguard Worker       __glXParseExtensionOverride(psc, tmp);
822*61046927SAndroid Build Coastguard Worker 
823*61046927SAndroid Build Coastguard Worker    if (dri2GalliumConfigQuerys(psc->frontend_screen,
824*61046927SAndroid Build Coastguard Worker                                     "indirect_gl_extension_override",
825*61046927SAndroid Build Coastguard Worker                                     &tmp) == 0)
826*61046927SAndroid Build Coastguard Worker       __IndirectGlParseExtensionOverride(psc, tmp);
827*61046927SAndroid Build Coastguard Worker 
828*61046927SAndroid Build Coastguard Worker    {
829*61046927SAndroid Build Coastguard Worker       uint8_t force = false;
830*61046927SAndroid Build Coastguard Worker       if (dri2GalliumConfigQueryb(psc->frontend_screen, "force_direct_glx_context",
831*61046927SAndroid Build Coastguard Worker                                     &force) == 0) {
832*61046927SAndroid Build Coastguard Worker          psc->force_direct_context = force;
833*61046927SAndroid Build Coastguard Worker       }
834*61046927SAndroid Build Coastguard Worker 
835*61046927SAndroid Build Coastguard Worker       uint8_t invalid_glx_destroy_window = false;
836*61046927SAndroid Build Coastguard Worker       if (dri2GalliumConfigQueryb(psc->frontend_screen,
837*61046927SAndroid Build Coastguard Worker                                     "allow_invalid_glx_destroy_window",
838*61046927SAndroid Build Coastguard Worker                                     &invalid_glx_destroy_window) == 0) {
839*61046927SAndroid Build Coastguard Worker          psc->allow_invalid_glx_destroy_window = invalid_glx_destroy_window;
840*61046927SAndroid Build Coastguard Worker       }
841*61046927SAndroid Build Coastguard Worker 
842*61046927SAndroid Build Coastguard Worker       uint8_t keep_native_window_glx_drawable = false;
843*61046927SAndroid Build Coastguard Worker       if (dri2GalliumConfigQueryb(psc->frontend_screen,
844*61046927SAndroid Build Coastguard Worker                                     "keep_native_window_glx_drawable",
845*61046927SAndroid Build Coastguard Worker                                     &keep_native_window_glx_drawable) == 0) {
846*61046927SAndroid Build Coastguard Worker          psc->keep_native_window_glx_drawable = keep_native_window_glx_drawable;
847*61046927SAndroid Build Coastguard Worker       }
848*61046927SAndroid Build Coastguard Worker    }
849*61046927SAndroid Build Coastguard Worker }
850*61046927SAndroid Build Coastguard Worker 
851*61046927SAndroid Build Coastguard Worker 
852*61046927SAndroid Build Coastguard Worker /*
853*61046927SAndroid Build Coastguard Worker ** Allocate the memory for the per screen configs for each screen.
854*61046927SAndroid Build Coastguard Worker ** If that works then fetch the per screen configs data.
855*61046927SAndroid Build Coastguard Worker */
856*61046927SAndroid Build Coastguard Worker static Bool
AllocAndFetchScreenConfigs(Display * dpy,struct glx_display * priv,enum glx_driver glx_driver,Bool driver_name_is_inferred)857*61046927SAndroid Build Coastguard Worker AllocAndFetchScreenConfigs(Display * dpy, struct glx_display * priv, enum glx_driver glx_driver, Bool driver_name_is_inferred)
858*61046927SAndroid Build Coastguard Worker {
859*61046927SAndroid Build Coastguard Worker    struct glx_screen *psc;
860*61046927SAndroid Build Coastguard Worker    GLint i, screens;
861*61046927SAndroid Build Coastguard Worker    unsigned screen_count = 0;
862*61046927SAndroid Build Coastguard Worker    bool zink = (glx_driver & (GLX_DRIVER_ZINK_INFER | GLX_DRIVER_ZINK_YES)) > 0;
863*61046927SAndroid Build Coastguard Worker 
864*61046927SAndroid Build Coastguard Worker    /*
865*61046927SAndroid Build Coastguard Worker     ** First allocate memory for the array of per screen configs.
866*61046927SAndroid Build Coastguard Worker     */
867*61046927SAndroid Build Coastguard Worker    screens = ScreenCount(dpy);
868*61046927SAndroid Build Coastguard Worker    priv->screens = calloc(screens, sizeof *priv->screens);
869*61046927SAndroid Build Coastguard Worker    if (!priv->screens)
870*61046927SAndroid Build Coastguard Worker       return GL_FALSE;
871*61046927SAndroid Build Coastguard Worker 
872*61046927SAndroid Build Coastguard Worker    for (i = 0; i < screens; i++) {
873*61046927SAndroid Build Coastguard Worker       psc = NULL;
874*61046927SAndroid Build Coastguard Worker #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
875*61046927SAndroid Build Coastguard Worker #if defined(GLX_USE_DRM)
876*61046927SAndroid Build Coastguard Worker       if (glx_driver & GLX_DRIVER_DRI3) {
877*61046927SAndroid Build Coastguard Worker          bool use_zink;
878*61046927SAndroid Build Coastguard Worker          psc = dri3_create_screen(i, priv, driver_name_is_inferred, &use_zink);
879*61046927SAndroid Build Coastguard Worker          if (use_zink) {
880*61046927SAndroid Build Coastguard Worker             glx_driver |= GLX_DRIVER_ZINK_YES;
881*61046927SAndroid Build Coastguard Worker             zink = true;
882*61046927SAndroid Build Coastguard Worker             driver_name_is_inferred = false;
883*61046927SAndroid Build Coastguard Worker          }
884*61046927SAndroid Build Coastguard Worker       }
885*61046927SAndroid Build Coastguard Worker #if defined(HAVE_X11_DRI2)
886*61046927SAndroid Build Coastguard Worker       if (psc == NULL && glx_driver & GLX_DRIVER_DRI2 && dri2CheckSupport(dpy)) {
887*61046927SAndroid Build Coastguard Worker 	      psc = dri2CreateScreen(i, priv, driver_name_is_inferred);
888*61046927SAndroid Build Coastguard Worker          if (psc)
889*61046927SAndroid Build Coastguard Worker             priv->dri2Hash = __glxHashCreate();
890*61046927SAndroid Build Coastguard Worker       }
891*61046927SAndroid Build Coastguard Worker #endif
892*61046927SAndroid Build Coastguard Worker #endif /* GLX_USE_DRM */
893*61046927SAndroid Build Coastguard Worker 
894*61046927SAndroid Build Coastguard Worker #ifdef GLX_USE_WINDOWSGL
895*61046927SAndroid Build Coastguard Worker       if (psc == NULL && glx_driver & GLX_DRIVER_WINDOWS) {
896*61046927SAndroid Build Coastguard Worker 	      psc = driwindowsCreateScreen(i, priv, driver_name_is_inferred);
897*61046927SAndroid Build Coastguard Worker       }
898*61046927SAndroid Build Coastguard Worker #endif
899*61046927SAndroid Build Coastguard Worker 
900*61046927SAndroid Build Coastguard Worker #endif /* GLX_DIRECT_RENDERING && !GLX_USE_APPLEGL */
901*61046927SAndroid Build Coastguard Worker #if defined(GLX_DIRECT_RENDERING) && (!defined(GLX_USE_APPLEGL) || defined(GLX_USE_APPLE))
902*61046927SAndroid Build Coastguard Worker       if (psc == NULL &&
903*61046927SAndroid Build Coastguard Worker           (glx_driver & GLX_DRIVER_SW || zink)) {
904*61046927SAndroid Build Coastguard Worker 	      psc = driswCreateScreen(i, priv, glx_driver, driver_name_is_inferred);
905*61046927SAndroid Build Coastguard Worker       }
906*61046927SAndroid Build Coastguard Worker #endif
907*61046927SAndroid Build Coastguard Worker 
908*61046927SAndroid Build Coastguard Worker       bool indirect = false;
909*61046927SAndroid Build Coastguard Worker 
910*61046927SAndroid Build Coastguard Worker #if defined(GLX_USE_APPLEGL) && !defined(GLX_USE_APPLE)
911*61046927SAndroid Build Coastguard Worker       if (psc == NULL)
912*61046927SAndroid Build Coastguard Worker          psc = applegl_create_screen(i, priv);
913*61046927SAndroid Build Coastguard Worker #else
914*61046927SAndroid Build Coastguard Worker       if (psc == NULL && !zink)
915*61046927SAndroid Build Coastguard Worker       {
916*61046927SAndroid Build Coastguard Worker          psc = indirect_create_screen(i, priv);
917*61046927SAndroid Build Coastguard Worker          indirect = true;
918*61046927SAndroid Build Coastguard Worker       }
919*61046927SAndroid Build Coastguard Worker #endif
920*61046927SAndroid Build Coastguard Worker       priv->screens[i] = psc;
921*61046927SAndroid Build Coastguard Worker       if (psc)
922*61046927SAndroid Build Coastguard Worker          screen_count++;
923*61046927SAndroid Build Coastguard Worker 
924*61046927SAndroid Build Coastguard Worker       if(indirect) /* Load extensions required only for indirect glx */
925*61046927SAndroid Build Coastguard Worker          glxSendClientInfo(priv, i);
926*61046927SAndroid Build Coastguard Worker       else if (priv->driver != GLX_DRIVER_WINDOWS)
927*61046927SAndroid Build Coastguard Worker          bind_extensions(psc, psc->driverName);
928*61046927SAndroid Build Coastguard Worker    }
929*61046927SAndroid Build Coastguard Worker    if (zink && !screen_count)
930*61046927SAndroid Build Coastguard Worker       return GL_FALSE;
931*61046927SAndroid Build Coastguard Worker    SyncHandle();
932*61046927SAndroid Build Coastguard Worker    return GL_TRUE;
933*61046927SAndroid Build Coastguard Worker }
934*61046927SAndroid Build Coastguard Worker 
935*61046927SAndroid Build Coastguard Worker /*
936*61046927SAndroid Build Coastguard Worker ** Initialize the client side extension code.
937*61046927SAndroid Build Coastguard Worker */
938*61046927SAndroid Build Coastguard Worker  _X_HIDDEN struct glx_display *
__glXInitialize(Display * dpy)939*61046927SAndroid Build Coastguard Worker __glXInitialize(Display * dpy)
940*61046927SAndroid Build Coastguard Worker {
941*61046927SAndroid Build Coastguard Worker    XExtCodes *codes;
942*61046927SAndroid Build Coastguard Worker    struct glx_display *dpyPriv, *d;
943*61046927SAndroid Build Coastguard Worker    int i, majorVersion = 0;
944*61046927SAndroid Build Coastguard Worker 
945*61046927SAndroid Build Coastguard Worker    _XLockMutex(_Xglobal_lock);
946*61046927SAndroid Build Coastguard Worker 
947*61046927SAndroid Build Coastguard Worker    for (dpyPriv = glx_displays; dpyPriv; dpyPriv = dpyPriv->next) {
948*61046927SAndroid Build Coastguard Worker       if (dpyPriv->dpy == dpy) {
949*61046927SAndroid Build Coastguard Worker 	 _XUnlockMutex(_Xglobal_lock);
950*61046927SAndroid Build Coastguard Worker 	 return dpyPriv;
951*61046927SAndroid Build Coastguard Worker       }
952*61046927SAndroid Build Coastguard Worker    }
953*61046927SAndroid Build Coastguard Worker 
954*61046927SAndroid Build Coastguard Worker    /* Drop the lock while we create the display private. */
955*61046927SAndroid Build Coastguard Worker    _XUnlockMutex(_Xglobal_lock);
956*61046927SAndroid Build Coastguard Worker 
957*61046927SAndroid Build Coastguard Worker    dpyPriv = calloc(1, sizeof *dpyPriv);
958*61046927SAndroid Build Coastguard Worker    if (!dpyPriv)
959*61046927SAndroid Build Coastguard Worker       return NULL;
960*61046927SAndroid Build Coastguard Worker 
961*61046927SAndroid Build Coastguard Worker    codes = XInitExtension(dpy, __glXExtensionName);
962*61046927SAndroid Build Coastguard Worker    if (!codes) {
963*61046927SAndroid Build Coastguard Worker       free(dpyPriv);
964*61046927SAndroid Build Coastguard Worker       return NULL;
965*61046927SAndroid Build Coastguard Worker    }
966*61046927SAndroid Build Coastguard Worker 
967*61046927SAndroid Build Coastguard Worker    dpyPriv->codes = *codes;
968*61046927SAndroid Build Coastguard Worker    dpyPriv->dpy = dpy;
969*61046927SAndroid Build Coastguard Worker 
970*61046927SAndroid Build Coastguard Worker    /* This GLX implementation requires GLX 1.3 */
971*61046927SAndroid Build Coastguard Worker    if (!QueryVersion(dpy, dpyPriv->codes.major_opcode,
972*61046927SAndroid Build Coastguard Worker 		     &majorVersion, &dpyPriv->minorVersion)
973*61046927SAndroid Build Coastguard Worker        || (majorVersion != 1)
974*61046927SAndroid Build Coastguard Worker        || (majorVersion == 1 && dpyPriv->minorVersion < 3)) {
975*61046927SAndroid Build Coastguard Worker       free(dpyPriv);
976*61046927SAndroid Build Coastguard Worker       return NULL;
977*61046927SAndroid Build Coastguard Worker    }
978*61046927SAndroid Build Coastguard Worker 
979*61046927SAndroid Build Coastguard Worker    for (i = 0; i < __GLX_NUMBER_EVENTS; i++) {
980*61046927SAndroid Build Coastguard Worker       XESetWireToEvent(dpy, dpyPriv->codes.first_event + i, __glXWireToEvent);
981*61046927SAndroid Build Coastguard Worker       XESetEventToWire(dpy, dpyPriv->codes.first_event + i, __glXEventToWire);
982*61046927SAndroid Build Coastguard Worker    }
983*61046927SAndroid Build Coastguard Worker 
984*61046927SAndroid Build Coastguard Worker    XESetCloseDisplay(dpy, dpyPriv->codes.extension, __glXCloseDisplay);
985*61046927SAndroid Build Coastguard Worker    XESetErrorString (dpy, dpyPriv->codes.extension, __glXErrorString);
986*61046927SAndroid Build Coastguard Worker 
987*61046927SAndroid Build Coastguard Worker    dpyPriv->glXDrawHash = __glxHashCreate();
988*61046927SAndroid Build Coastguard Worker 
989*61046927SAndroid Build Coastguard Worker    enum glx_driver glx_driver = 0;
990*61046927SAndroid Build Coastguard Worker    const char *env = getenv("MESA_LOADER_DRIVER_OVERRIDE");
991*61046927SAndroid Build Coastguard Worker 
992*61046927SAndroid Build Coastguard Worker #if defined(GLX_DIRECT_RENDERING) && (!defined(GLX_USE_APPLEGL) || defined(GLX_USE_APPLE))
993*61046927SAndroid Build Coastguard Worker    Bool glx_direct = !debug_get_bool_option("LIBGL_ALWAYS_INDIRECT", false);
994*61046927SAndroid Build Coastguard Worker    Bool glx_accel = !debug_get_bool_option("LIBGL_ALWAYS_SOFTWARE", false);
995*61046927SAndroid Build Coastguard Worker    Bool dri3 = !debug_get_bool_option("LIBGL_DRI3_DISABLE", false);
996*61046927SAndroid Build Coastguard Worker    Bool kopper = !debug_get_bool_option("LIBGL_KOPPER_DISABLE", false);
997*61046927SAndroid Build Coastguard Worker 
998*61046927SAndroid Build Coastguard Worker    if (env && !strcmp(env, "zink"))
999*61046927SAndroid Build Coastguard Worker       glx_driver |= GLX_DRIVER_ZINK_YES;
1000*61046927SAndroid Build Coastguard Worker 
1001*61046927SAndroid Build Coastguard Worker    dpyPriv->drawHash = __glxHashCreate();
1002*61046927SAndroid Build Coastguard Worker 
1003*61046927SAndroid Build Coastguard Worker    dpyPriv->zombieGLXDrawable = _mesa_pointer_set_create(NULL);
1004*61046927SAndroid Build Coastguard Worker 
1005*61046927SAndroid Build Coastguard Worker    /* Set the logger before the *CreateDisplay functions. */
1006*61046927SAndroid Build Coastguard Worker    loader_set_logger(glx_message);
1007*61046927SAndroid Build Coastguard Worker 
1008*61046927SAndroid Build Coastguard Worker    /*
1009*61046927SAndroid Build Coastguard Worker     ** Initialize the direct rendering per display data and functions.
1010*61046927SAndroid Build Coastguard Worker     ** Note: This _must_ be done before calling any other DRI routines
1011*61046927SAndroid Build Coastguard Worker     ** (e.g., those called in AllocAndFetchScreenConfigs).
1012*61046927SAndroid Build Coastguard Worker     */
1013*61046927SAndroid Build Coastguard Worker #if defined(GLX_USE_DRM)
1014*61046927SAndroid Build Coastguard Worker    bool dri3_err = false;
1015*61046927SAndroid Build Coastguard Worker    if (glx_direct && glx_accel && dri3)
1016*61046927SAndroid Build Coastguard Worker       dpyPriv->has_multibuffer = x11_dri3_check_multibuffer(XGetXCBConnection(dpy), &dri3_err, &dpyPriv->has_explicit_modifiers);
1017*61046927SAndroid Build Coastguard Worker    if (glx_direct && glx_accel &&
1018*61046927SAndroid Build Coastguard Worker        (!(glx_driver & GLX_DRIVER_ZINK_YES) || !kopper)) {
1019*61046927SAndroid Build Coastguard Worker       if (dri3) {
1020*61046927SAndroid Build Coastguard Worker          /* dri3 is tried as long as this doesn't error; whether modifiers work is not relevant */
1021*61046927SAndroid Build Coastguard Worker          if (!dri3_err) {
1022*61046927SAndroid Build Coastguard Worker             glx_driver |= GLX_DRIVER_DRI3;
1023*61046927SAndroid Build Coastguard Worker             /* nouveau wants to fallback to zink so if we get a screen enable try_zink */
1024*61046927SAndroid Build Coastguard Worker             if (!debug_get_bool_option("LIBGL_KOPPER_DISABLE", false))
1025*61046927SAndroid Build Coastguard Worker                glx_driver |= GLX_DRIVER_ZINK_INFER;
1026*61046927SAndroid Build Coastguard Worker          }
1027*61046927SAndroid Build Coastguard Worker       }
1028*61046927SAndroid Build Coastguard Worker #if defined(HAVE_X11_DRI2)
1029*61046927SAndroid Build Coastguard Worker       if (!debug_get_bool_option("LIBGL_DRI2_DISABLE", false))
1030*61046927SAndroid Build Coastguard Worker          glx_driver |= GLX_DRIVER_DRI2;
1031*61046927SAndroid Build Coastguard Worker #endif
1032*61046927SAndroid Build Coastguard Worker #if defined(HAVE_ZINK)
1033*61046927SAndroid Build Coastguard Worker       if (!(glx_driver & (GLX_DRIVER_DRI2 | GLX_DRIVER_DRI3)))
1034*61046927SAndroid Build Coastguard Worker          if (kopper && !getenv("GALLIUM_DRIVER"))
1035*61046927SAndroid Build Coastguard Worker             glx_driver |= GLX_DRIVER_ZINK_INFER;
1036*61046927SAndroid Build Coastguard Worker #endif /* HAVE_ZINK */
1037*61046927SAndroid Build Coastguard Worker    }
1038*61046927SAndroid Build Coastguard Worker #endif /* GLX_USE_DRM */
1039*61046927SAndroid Build Coastguard Worker    if (glx_direct)
1040*61046927SAndroid Build Coastguard Worker       glx_driver |= GLX_DRIVER_SW;
1041*61046927SAndroid Build Coastguard Worker 
1042*61046927SAndroid Build Coastguard Worker    if (!dpyPriv->has_explicit_modifiers && glx_accel && !debug_get_bool_option("LIBGL_KOPPER_DRI2", false)) {
1043*61046927SAndroid Build Coastguard Worker       if (glx_driver & GLX_DRIVER_ZINK_YES) {
1044*61046927SAndroid Build Coastguard Worker          /* only print error if zink was explicitly requested */
1045*61046927SAndroid Build Coastguard Worker          CriticalErrorMessageF("DRI3 not available\n");
1046*61046927SAndroid Build Coastguard Worker          free(dpyPriv);
1047*61046927SAndroid Build Coastguard Worker          return NULL;
1048*61046927SAndroid Build Coastguard Worker       }
1049*61046927SAndroid Build Coastguard Worker       /* if no dri3 and not using dri2, disable zink */
1050*61046927SAndroid Build Coastguard Worker       glx_driver &= ~GLX_DRIVER_ZINK_INFER;
1051*61046927SAndroid Build Coastguard Worker    }
1052*61046927SAndroid Build Coastguard Worker 
1053*61046927SAndroid Build Coastguard Worker #ifdef GLX_USE_WINDOWSGL
1054*61046927SAndroid Build Coastguard Worker    if (glx_direct && glx_accel)
1055*61046927SAndroid Build Coastguard Worker       glx_driver |= GLX_DRIVER_WINDOWS;
1056*61046927SAndroid Build Coastguard Worker #else
1057*61046927SAndroid Build Coastguard Worker #ifndef RTLD_NOW
1058*61046927SAndroid Build Coastguard Worker #define RTLD_NOW 0
1059*61046927SAndroid Build Coastguard Worker #endif
1060*61046927SAndroid Build Coastguard Worker #ifndef RTLD_GLOBAL
1061*61046927SAndroid Build Coastguard Worker #define RTLD_GLOBAL 0
1062*61046927SAndroid Build Coastguard Worker #endif
1063*61046927SAndroid Build Coastguard Worker 
1064*61046927SAndroid Build Coastguard Worker #ifndef GL_LIB_NAME
1065*61046927SAndroid Build Coastguard Worker #define GL_LIB_NAME "libGL.so.1"
1066*61046927SAndroid Build Coastguard Worker #endif
1067*61046927SAndroid Build Coastguard Worker 
1068*61046927SAndroid Build Coastguard Worker    void *glhandle = dlopen(GL_LIB_NAME, RTLD_NOW | RTLD_GLOBAL);
1069*61046927SAndroid Build Coastguard Worker    if (glhandle)
1070*61046927SAndroid Build Coastguard Worker       dlclose(glhandle);
1071*61046927SAndroid Build Coastguard Worker 
1072*61046927SAndroid Build Coastguard Worker #endif
1073*61046927SAndroid Build Coastguard Worker #endif /* GLX_DIRECT_RENDERING && !GLX_USE_APPLEGL */
1074*61046927SAndroid Build Coastguard Worker 
1075*61046927SAndroid Build Coastguard Worker #if defined(GLX_USE_APPLEGL) && !defined(GLX_USE_APPLE)
1076*61046927SAndroid Build Coastguard Worker    glx_driver |= GLX_DRIVER_SW;
1077*61046927SAndroid Build Coastguard Worker #endif
1078*61046927SAndroid Build Coastguard Worker 
1079*61046927SAndroid Build Coastguard Worker    if (!AllocAndFetchScreenConfigs(dpy, dpyPriv, glx_driver, !env)) {
1080*61046927SAndroid Build Coastguard Worker       Bool fail = True;
1081*61046927SAndroid Build Coastguard Worker #if defined(GLX_DIRECT_RENDERING) && (!defined(GLX_USE_APPLEGL) || defined(GLX_USE_APPLE))
1082*61046927SAndroid Build Coastguard Worker       if (glx_driver & GLX_DRIVER_ZINK_INFER) {
1083*61046927SAndroid Build Coastguard Worker          fail = !AllocAndFetchScreenConfigs(dpy, dpyPriv, GLX_DRIVER_SW, true);
1084*61046927SAndroid Build Coastguard Worker       }
1085*61046927SAndroid Build Coastguard Worker #endif
1086*61046927SAndroid Build Coastguard Worker       if (fail) {
1087*61046927SAndroid Build Coastguard Worker          free(dpyPriv);
1088*61046927SAndroid Build Coastguard Worker          return NULL;
1089*61046927SAndroid Build Coastguard Worker       }
1090*61046927SAndroid Build Coastguard Worker    }
1091*61046927SAndroid Build Coastguard Worker 
1092*61046927SAndroid Build Coastguard Worker    glxSendClientInfo(dpyPriv, -1);
1093*61046927SAndroid Build Coastguard Worker 
1094*61046927SAndroid Build Coastguard Worker    /* Grab the lock again and add the display private, unless somebody
1095*61046927SAndroid Build Coastguard Worker     * beat us to initializing on this display in the meantime. */
1096*61046927SAndroid Build Coastguard Worker    _XLockMutex(_Xglobal_lock);
1097*61046927SAndroid Build Coastguard Worker 
1098*61046927SAndroid Build Coastguard Worker    for (d = glx_displays; d; d = d->next) {
1099*61046927SAndroid Build Coastguard Worker       if (d->dpy == dpy) {
1100*61046927SAndroid Build Coastguard Worker 	 _XUnlockMutex(_Xglobal_lock);
1101*61046927SAndroid Build Coastguard Worker 	 glx_display_free(dpyPriv);
1102*61046927SAndroid Build Coastguard Worker 	 return d;
1103*61046927SAndroid Build Coastguard Worker       }
1104*61046927SAndroid Build Coastguard Worker    }
1105*61046927SAndroid Build Coastguard Worker 
1106*61046927SAndroid Build Coastguard Worker    dpyPriv->next = glx_displays;
1107*61046927SAndroid Build Coastguard Worker    glx_displays = dpyPriv;
1108*61046927SAndroid Build Coastguard Worker 
1109*61046927SAndroid Build Coastguard Worker    _XUnlockMutex(_Xglobal_lock);
1110*61046927SAndroid Build Coastguard Worker 
1111*61046927SAndroid Build Coastguard Worker    return dpyPriv;
1112*61046927SAndroid Build Coastguard Worker }
1113*61046927SAndroid Build Coastguard Worker 
1114*61046927SAndroid Build Coastguard Worker /*
1115*61046927SAndroid Build Coastguard Worker ** Setup for sending a GLX command on dpy.  Make sure the extension is
1116*61046927SAndroid Build Coastguard Worker ** initialized.  Try to avoid calling __glXInitialize as its kinda slow.
1117*61046927SAndroid Build Coastguard Worker */
1118*61046927SAndroid Build Coastguard Worker _X_HIDDEN CARD8
__glXSetupForCommand(Display * dpy)1119*61046927SAndroid Build Coastguard Worker __glXSetupForCommand(Display * dpy)
1120*61046927SAndroid Build Coastguard Worker {
1121*61046927SAndroid Build Coastguard Worker     struct glx_context *gc;
1122*61046927SAndroid Build Coastguard Worker     struct glx_display *priv;
1123*61046927SAndroid Build Coastguard Worker 
1124*61046927SAndroid Build Coastguard Worker    /* If this thread has a current context, flush its rendering commands */
1125*61046927SAndroid Build Coastguard Worker    gc = __glXGetCurrentContext();
1126*61046927SAndroid Build Coastguard Worker    if (gc->currentDpy) {
1127*61046927SAndroid Build Coastguard Worker       /* Flush rendering buffer of the current context, if any */
1128*61046927SAndroid Build Coastguard Worker       (void) __glXFlushRenderBuffer(gc, gc->pc);
1129*61046927SAndroid Build Coastguard Worker 
1130*61046927SAndroid Build Coastguard Worker       if (gc->currentDpy == dpy) {
1131*61046927SAndroid Build Coastguard Worker          /* Use opcode from gc because its right */
1132*61046927SAndroid Build Coastguard Worker          return gc->majorOpcode;
1133*61046927SAndroid Build Coastguard Worker       }
1134*61046927SAndroid Build Coastguard Worker       else {
1135*61046927SAndroid Build Coastguard Worker          /*
1136*61046927SAndroid Build Coastguard Worker           ** Have to get info about argument dpy because it might be to
1137*61046927SAndroid Build Coastguard Worker           ** a different server
1138*61046927SAndroid Build Coastguard Worker           */
1139*61046927SAndroid Build Coastguard Worker       }
1140*61046927SAndroid Build Coastguard Worker    }
1141*61046927SAndroid Build Coastguard Worker 
1142*61046927SAndroid Build Coastguard Worker    /* Forced to lookup extension via the slow initialize route */
1143*61046927SAndroid Build Coastguard Worker    priv = __glXInitialize(dpy);
1144*61046927SAndroid Build Coastguard Worker    if (!priv) {
1145*61046927SAndroid Build Coastguard Worker       return 0;
1146*61046927SAndroid Build Coastguard Worker    }
1147*61046927SAndroid Build Coastguard Worker    return priv->codes.major_opcode;
1148*61046927SAndroid Build Coastguard Worker }
1149*61046927SAndroid Build Coastguard Worker 
1150*61046927SAndroid Build Coastguard Worker /**
1151*61046927SAndroid Build Coastguard Worker  * Flush the drawing command transport buffer.
1152*61046927SAndroid Build Coastguard Worker  *
1153*61046927SAndroid Build Coastguard Worker  * \param ctx  Context whose transport buffer is to be flushed.
1154*61046927SAndroid Build Coastguard Worker  * \param pc   Pointer to first unused buffer location.
1155*61046927SAndroid Build Coastguard Worker  *
1156*61046927SAndroid Build Coastguard Worker  * \todo
1157*61046927SAndroid Build Coastguard Worker  * Modify this function to use \c ctx->pc instead of the explicit
1158*61046927SAndroid Build Coastguard Worker  * \c pc parameter.
1159*61046927SAndroid Build Coastguard Worker  */
1160*61046927SAndroid Build Coastguard Worker _X_HIDDEN GLubyte *
__glXFlushRenderBuffer(struct glx_context * ctx,GLubyte * pc)1161*61046927SAndroid Build Coastguard Worker __glXFlushRenderBuffer(struct glx_context * ctx, GLubyte * pc)
1162*61046927SAndroid Build Coastguard Worker {
1163*61046927SAndroid Build Coastguard Worker    Display *const dpy = ctx->currentDpy;
1164*61046927SAndroid Build Coastguard Worker    xcb_connection_t *c = XGetXCBConnection(dpy);
1165*61046927SAndroid Build Coastguard Worker    const GLint size = pc - ctx->buf;
1166*61046927SAndroid Build Coastguard Worker 
1167*61046927SAndroid Build Coastguard Worker    if ((dpy != NULL) && (size > 0)) {
1168*61046927SAndroid Build Coastguard Worker       xcb_glx_render(c, ctx->currentContextTag, size,
1169*61046927SAndroid Build Coastguard Worker                      (const uint8_t *) ctx->buf);
1170*61046927SAndroid Build Coastguard Worker    }
1171*61046927SAndroid Build Coastguard Worker 
1172*61046927SAndroid Build Coastguard Worker    /* Reset pointer and return it */
1173*61046927SAndroid Build Coastguard Worker    ctx->pc = ctx->buf;
1174*61046927SAndroid Build Coastguard Worker    return ctx->pc;
1175*61046927SAndroid Build Coastguard Worker }
1176*61046927SAndroid Build Coastguard Worker 
1177*61046927SAndroid Build Coastguard Worker 
1178*61046927SAndroid Build Coastguard Worker /**
1179*61046927SAndroid Build Coastguard Worker  * Send a portion of a GLXRenderLarge command to the server.  The advantage of
1180*61046927SAndroid Build Coastguard Worker  * this function over \c __glXSendLargeCommand is that callers can use the
1181*61046927SAndroid Build Coastguard Worker  * data buffer in the GLX context and may be able to avoid allocating an
1182*61046927SAndroid Build Coastguard Worker  * extra buffer.  The disadvantage is the clients will have to do more
1183*61046927SAndroid Build Coastguard Worker  * GLX protocol work (i.e., calculating \c totalRequests, etc.).
1184*61046927SAndroid Build Coastguard Worker  *
1185*61046927SAndroid Build Coastguard Worker  * \sa __glXSendLargeCommand
1186*61046927SAndroid Build Coastguard Worker  *
1187*61046927SAndroid Build Coastguard Worker  * \param gc             GLX context
1188*61046927SAndroid Build Coastguard Worker  * \param requestNumber  Which part of the whole command is this?  The first
1189*61046927SAndroid Build Coastguard Worker  *                       request is 1.
1190*61046927SAndroid Build Coastguard Worker  * \param totalRequests  How many requests will there be?
1191*61046927SAndroid Build Coastguard Worker  * \param data           Command data.
1192*61046927SAndroid Build Coastguard Worker  * \param dataLen        Size, in bytes, of the command data.
1193*61046927SAndroid Build Coastguard Worker  */
1194*61046927SAndroid Build Coastguard Worker _X_HIDDEN void
__glXSendLargeChunk(struct glx_context * gc,GLint requestNumber,GLint totalRequests,const GLvoid * data,GLint dataLen)1195*61046927SAndroid Build Coastguard Worker __glXSendLargeChunk(struct glx_context * gc, GLint requestNumber,
1196*61046927SAndroid Build Coastguard Worker                     GLint totalRequests, const GLvoid * data, GLint dataLen)
1197*61046927SAndroid Build Coastguard Worker {
1198*61046927SAndroid Build Coastguard Worker    Display *dpy = gc->currentDpy;
1199*61046927SAndroid Build Coastguard Worker    xcb_connection_t *c = XGetXCBConnection(dpy);
1200*61046927SAndroid Build Coastguard Worker    xcb_glx_render_large(c, gc->currentContextTag, requestNumber,
1201*61046927SAndroid Build Coastguard Worker                         totalRequests, dataLen, data);
1202*61046927SAndroid Build Coastguard Worker }
1203*61046927SAndroid Build Coastguard Worker 
1204*61046927SAndroid Build Coastguard Worker 
1205*61046927SAndroid Build Coastguard Worker /**
1206*61046927SAndroid Build Coastguard Worker  * Send a command that is too large for the GLXRender protocol request.
1207*61046927SAndroid Build Coastguard Worker  *
1208*61046927SAndroid Build Coastguard Worker  * Send a large command, one that is too large for some reason to
1209*61046927SAndroid Build Coastguard Worker  * send using the GLXRender protocol request.  One reason to send
1210*61046927SAndroid Build Coastguard Worker  * a large command is to avoid copying the data.
1211*61046927SAndroid Build Coastguard Worker  *
1212*61046927SAndroid Build Coastguard Worker  * \param ctx        GLX context
1213*61046927SAndroid Build Coastguard Worker  * \param header     Header data.
1214*61046927SAndroid Build Coastguard Worker  * \param headerLen  Size, in bytes, of the header data.  It is assumed that
1215*61046927SAndroid Build Coastguard Worker  *                   the header data will always be small enough to fit in
1216*61046927SAndroid Build Coastguard Worker  *                   a single X protocol packet.
1217*61046927SAndroid Build Coastguard Worker  * \param data       Command data.
1218*61046927SAndroid Build Coastguard Worker  * \param dataLen    Size, in bytes, of the command data.
1219*61046927SAndroid Build Coastguard Worker  */
1220*61046927SAndroid Build Coastguard Worker _X_HIDDEN void
__glXSendLargeCommand(struct glx_context * ctx,const GLvoid * header,GLint headerLen,const GLvoid * data,GLint dataLen)1221*61046927SAndroid Build Coastguard Worker __glXSendLargeCommand(struct glx_context * ctx,
1222*61046927SAndroid Build Coastguard Worker                       const GLvoid * header, GLint headerLen,
1223*61046927SAndroid Build Coastguard Worker                       const GLvoid * data, GLint dataLen)
1224*61046927SAndroid Build Coastguard Worker {
1225*61046927SAndroid Build Coastguard Worker    GLint maxSize;
1226*61046927SAndroid Build Coastguard Worker    GLint totalRequests, requestNumber;
1227*61046927SAndroid Build Coastguard Worker 
1228*61046927SAndroid Build Coastguard Worker    /*
1229*61046927SAndroid Build Coastguard Worker     ** Calculate the maximum amount of data can be stuffed into a single
1230*61046927SAndroid Build Coastguard Worker     ** packet.  sz_xGLXRenderReq is added because bufSize is the maximum
1231*61046927SAndroid Build Coastguard Worker     ** packet size minus sz_xGLXRenderReq.
1232*61046927SAndroid Build Coastguard Worker     */
1233*61046927SAndroid Build Coastguard Worker    maxSize = (ctx->bufSize + sz_xGLXRenderReq) - sz_xGLXRenderLargeReq;
1234*61046927SAndroid Build Coastguard Worker    totalRequests = 1 + (dataLen / maxSize);
1235*61046927SAndroid Build Coastguard Worker    if (dataLen % maxSize)
1236*61046927SAndroid Build Coastguard Worker       totalRequests++;
1237*61046927SAndroid Build Coastguard Worker 
1238*61046927SAndroid Build Coastguard Worker    /*
1239*61046927SAndroid Build Coastguard Worker     ** Send all of the command, except the large array, as one request.
1240*61046927SAndroid Build Coastguard Worker     */
1241*61046927SAndroid Build Coastguard Worker    assert(headerLen <= maxSize);
1242*61046927SAndroid Build Coastguard Worker    __glXSendLargeChunk(ctx, 1, totalRequests, header, headerLen);
1243*61046927SAndroid Build Coastguard Worker 
1244*61046927SAndroid Build Coastguard Worker    /*
1245*61046927SAndroid Build Coastguard Worker     ** Send enough requests until the whole array is sent.
1246*61046927SAndroid Build Coastguard Worker     */
1247*61046927SAndroid Build Coastguard Worker    for (requestNumber = 2; requestNumber <= (totalRequests - 1);
1248*61046927SAndroid Build Coastguard Worker         requestNumber++) {
1249*61046927SAndroid Build Coastguard Worker       __glXSendLargeChunk(ctx, requestNumber, totalRequests, data, maxSize);
1250*61046927SAndroid Build Coastguard Worker       data = (const GLvoid *) (((const GLubyte *) data) + maxSize);
1251*61046927SAndroid Build Coastguard Worker       dataLen -= maxSize;
1252*61046927SAndroid Build Coastguard Worker       assert(dataLen > 0);
1253*61046927SAndroid Build Coastguard Worker    }
1254*61046927SAndroid Build Coastguard Worker 
1255*61046927SAndroid Build Coastguard Worker    assert(dataLen <= maxSize);
1256*61046927SAndroid Build Coastguard Worker    __glXSendLargeChunk(ctx, requestNumber, totalRequests, data, dataLen);
1257*61046927SAndroid Build Coastguard Worker }
1258