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