xref: /aosp_15_r20/external/mesa3d/src/glx/indirect_glx.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2010 Intel Corporation
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Soft-
6*61046927SAndroid Build Coastguard Worker  * ware"), to deal in the Software without restriction, including without
7*61046927SAndroid Build Coastguard Worker  * limitation the rights to use, copy, modify, merge, publish, distribute,
8*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, provided that the above copyright
10*61046927SAndroid Build Coastguard Worker  * notice(s) and this permission notice appear in all copies of the Soft-
11*61046927SAndroid Build Coastguard Worker  * ware and that both the above copyright notice(s) and this permission
12*61046927SAndroid Build Coastguard Worker  * notice appear in supporting documentation.
13*61046927SAndroid Build Coastguard Worker  *
14*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15*61046927SAndroid Build Coastguard Worker  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
16*61046927SAndroid Build Coastguard Worker  * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
17*61046927SAndroid Build Coastguard Worker  * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
18*61046927SAndroid Build Coastguard Worker  * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
19*61046927SAndroid Build Coastguard Worker  * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20*61046927SAndroid Build Coastguard Worker  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21*61046927SAndroid Build Coastguard Worker  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
22*61046927SAndroid Build Coastguard Worker  * MANCE OF THIS SOFTWARE.
23*61046927SAndroid Build Coastguard Worker  *
24*61046927SAndroid Build Coastguard Worker  * Except as contained in this notice, the name of a copyright holder shall
25*61046927SAndroid Build Coastguard Worker  * not be used in advertising or otherwise to promote the sale, use or
26*61046927SAndroid Build Coastguard Worker  * other dealings in this Software without prior written authorization of
27*61046927SAndroid Build Coastguard Worker  * the copyright holder.
28*61046927SAndroid Build Coastguard Worker  *
29*61046927SAndroid Build Coastguard Worker  * Authors:
30*61046927SAndroid Build Coastguard Worker  *   Kristian Høgsberg ([email protected])
31*61046927SAndroid Build Coastguard Worker  */
32*61046927SAndroid Build Coastguard Worker 
33*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
34*61046927SAndroid Build Coastguard Worker 
35*61046927SAndroid Build Coastguard Worker #include "glapi.h"
36*61046927SAndroid Build Coastguard Worker #include "glxclient.h"
37*61046927SAndroid Build Coastguard Worker #include "indirect.h"
38*61046927SAndroid Build Coastguard Worker #include "util/u_debug.h"
39*61046927SAndroid Build Coastguard Worker 
40*61046927SAndroid Build Coastguard Worker #if !defined(GLX_USE_APPLEGL) || defined(GLX_USE_APPLE)
41*61046927SAndroid Build Coastguard Worker 
42*61046927SAndroid Build Coastguard Worker extern struct _glapi_table *__glXNewIndirectAPI(void);
43*61046927SAndroid Build Coastguard Worker 
44*61046927SAndroid Build Coastguard Worker /*
45*61046927SAndroid Build Coastguard Worker ** All indirect rendering contexts will share the same indirect dispatch table.
46*61046927SAndroid Build Coastguard Worker */
47*61046927SAndroid Build Coastguard Worker static struct _glapi_table *IndirectAPI = NULL;
48*61046927SAndroid Build Coastguard Worker 
49*61046927SAndroid Build Coastguard Worker static void
__glFreeAttributeState(struct glx_context * gc)50*61046927SAndroid Build Coastguard Worker __glFreeAttributeState(struct glx_context * gc)
51*61046927SAndroid Build Coastguard Worker {
52*61046927SAndroid Build Coastguard Worker    __GLXattribute *sp, **spp;
53*61046927SAndroid Build Coastguard Worker 
54*61046927SAndroid Build Coastguard Worker    for (spp = &gc->attributes.stack[0];
55*61046927SAndroid Build Coastguard Worker         spp < &gc->attributes.stack[__GL_CLIENT_ATTRIB_STACK_DEPTH]; spp++) {
56*61046927SAndroid Build Coastguard Worker       sp = *spp;
57*61046927SAndroid Build Coastguard Worker       if (sp) {
58*61046927SAndroid Build Coastguard Worker          free((char *) sp);
59*61046927SAndroid Build Coastguard Worker       }
60*61046927SAndroid Build Coastguard Worker       else {
61*61046927SAndroid Build Coastguard Worker          break;
62*61046927SAndroid Build Coastguard Worker       }
63*61046927SAndroid Build Coastguard Worker    }
64*61046927SAndroid Build Coastguard Worker }
65*61046927SAndroid Build Coastguard Worker 
66*61046927SAndroid Build Coastguard Worker static void
indirect_destroy_context(struct glx_context * gc)67*61046927SAndroid Build Coastguard Worker indirect_destroy_context(struct glx_context *gc)
68*61046927SAndroid Build Coastguard Worker {
69*61046927SAndroid Build Coastguard Worker    __glXFreeVertexArrayState(gc);
70*61046927SAndroid Build Coastguard Worker 
71*61046927SAndroid Build Coastguard Worker    free((char *) gc->vendor);
72*61046927SAndroid Build Coastguard Worker    free((char *) gc->renderer);
73*61046927SAndroid Build Coastguard Worker    free((char *) gc->version);
74*61046927SAndroid Build Coastguard Worker    free((char *) gc->extensions);
75*61046927SAndroid Build Coastguard Worker    __glFreeAttributeState(gc);
76*61046927SAndroid Build Coastguard Worker    free((char *) gc->buf);
77*61046927SAndroid Build Coastguard Worker    free((char *) gc->client_state_private);
78*61046927SAndroid Build Coastguard Worker    free((char *) gc);
79*61046927SAndroid Build Coastguard Worker }
80*61046927SAndroid Build Coastguard Worker 
81*61046927SAndroid Build Coastguard Worker static Bool
SendMakeCurrentRequest(Display * dpy,GLXContextID gc_id,GLXContextTag gc_tag,GLXDrawable draw,GLXDrawable read,GLXContextTag * out_tag)82*61046927SAndroid Build Coastguard Worker SendMakeCurrentRequest(Display * dpy, GLXContextID gc_id,
83*61046927SAndroid Build Coastguard Worker                        GLXContextTag gc_tag, GLXDrawable draw,
84*61046927SAndroid Build Coastguard Worker                        GLXDrawable read, GLXContextTag *out_tag)
85*61046927SAndroid Build Coastguard Worker {
86*61046927SAndroid Build Coastguard Worker    xGLXMakeCurrentReply reply;
87*61046927SAndroid Build Coastguard Worker    Bool ret;
88*61046927SAndroid Build Coastguard Worker    int opcode = __glXSetupForCommand(dpy);
89*61046927SAndroid Build Coastguard Worker 
90*61046927SAndroid Build Coastguard Worker    LockDisplay(dpy);
91*61046927SAndroid Build Coastguard Worker 
92*61046927SAndroid Build Coastguard Worker    if (draw == read) {
93*61046927SAndroid Build Coastguard Worker       xGLXMakeCurrentReq *req;
94*61046927SAndroid Build Coastguard Worker 
95*61046927SAndroid Build Coastguard Worker       GetReq(GLXMakeCurrent, req);
96*61046927SAndroid Build Coastguard Worker       req->reqType = opcode;
97*61046927SAndroid Build Coastguard Worker       req->glxCode = X_GLXMakeCurrent;
98*61046927SAndroid Build Coastguard Worker       req->drawable = draw;
99*61046927SAndroid Build Coastguard Worker       req->context = gc_id;
100*61046927SAndroid Build Coastguard Worker       req->oldContextTag = gc_tag;
101*61046927SAndroid Build Coastguard Worker    }
102*61046927SAndroid Build Coastguard Worker    else {
103*61046927SAndroid Build Coastguard Worker       xGLXMakeContextCurrentReq *req;
104*61046927SAndroid Build Coastguard Worker 
105*61046927SAndroid Build Coastguard Worker       GetReq(GLXMakeContextCurrent, req);
106*61046927SAndroid Build Coastguard Worker       req->reqType = opcode;
107*61046927SAndroid Build Coastguard Worker       req->glxCode = X_GLXMakeContextCurrent;
108*61046927SAndroid Build Coastguard Worker       req->drawable = draw;
109*61046927SAndroid Build Coastguard Worker       req->readdrawable = read;
110*61046927SAndroid Build Coastguard Worker       req->context = gc_id;
111*61046927SAndroid Build Coastguard Worker       req->oldContextTag = gc_tag;
112*61046927SAndroid Build Coastguard Worker    }
113*61046927SAndroid Build Coastguard Worker 
114*61046927SAndroid Build Coastguard Worker    ret = _XReply(dpy, (xReply *) &reply, 0, False);
115*61046927SAndroid Build Coastguard Worker 
116*61046927SAndroid Build Coastguard Worker    if (out_tag)
117*61046927SAndroid Build Coastguard Worker       *out_tag = reply.contextTag;
118*61046927SAndroid Build Coastguard Worker 
119*61046927SAndroid Build Coastguard Worker    UnlockDisplay(dpy);
120*61046927SAndroid Build Coastguard Worker    SyncHandle();
121*61046927SAndroid Build Coastguard Worker 
122*61046927SAndroid Build Coastguard Worker    return ret;
123*61046927SAndroid Build Coastguard Worker }
124*61046927SAndroid Build Coastguard Worker 
125*61046927SAndroid Build Coastguard Worker static int
indirect_bind_context(struct glx_context * gc,GLXDrawable draw,GLXDrawable read)126*61046927SAndroid Build Coastguard Worker indirect_bind_context(struct glx_context *gc,
127*61046927SAndroid Build Coastguard Worker             GLXDrawable draw, GLXDrawable read)
128*61046927SAndroid Build Coastguard Worker {
129*61046927SAndroid Build Coastguard Worker    Display *dpy = gc->psc->dpy;
130*61046927SAndroid Build Coastguard Worker    Bool sent;
131*61046927SAndroid Build Coastguard Worker 
132*61046927SAndroid Build Coastguard Worker    sent = SendMakeCurrentRequest(dpy, gc->xid, 0, draw, read,
133*61046927SAndroid Build Coastguard Worker              &gc->currentContextTag);
134*61046927SAndroid Build Coastguard Worker 
135*61046927SAndroid Build Coastguard Worker    if (sent) {
136*61046927SAndroid Build Coastguard Worker       if (!IndirectAPI)
137*61046927SAndroid Build Coastguard Worker          IndirectAPI = __glXNewIndirectAPI();
138*61046927SAndroid Build Coastguard Worker       _glapi_set_dispatch(IndirectAPI);
139*61046927SAndroid Build Coastguard Worker 
140*61046927SAndroid Build Coastguard Worker       /* The indirect vertex array state must to be initialised after we
141*61046927SAndroid Build Coastguard Worker        * have setup the context, as it needs to query server attributes.
142*61046927SAndroid Build Coastguard Worker        *
143*61046927SAndroid Build Coastguard Worker        * At the point this is called gc->currentDpy is not initialized
144*61046927SAndroid Build Coastguard Worker        * nor is the thread's current context actually set. Hence the
145*61046927SAndroid Build Coastguard Worker        * cleverness before the GetString calls.
146*61046927SAndroid Build Coastguard Worker        */
147*61046927SAndroid Build Coastguard Worker       __GLXattribute *state = gc->client_state_private;
148*61046927SAndroid Build Coastguard Worker       if (state && state->array_state == NULL) {
149*61046927SAndroid Build Coastguard Worker          gc->currentDpy = gc->psc->dpy;
150*61046927SAndroid Build Coastguard Worker          __glXSetCurrentContext(gc);
151*61046927SAndroid Build Coastguard Worker          __indirect_glGetString(GL_EXTENSIONS);
152*61046927SAndroid Build Coastguard Worker          __indirect_glGetString(GL_VERSION);
153*61046927SAndroid Build Coastguard Worker          __glXInitVertexArrayState(gc);
154*61046927SAndroid Build Coastguard Worker       }
155*61046927SAndroid Build Coastguard Worker    }
156*61046927SAndroid Build Coastguard Worker 
157*61046927SAndroid Build Coastguard Worker    return !sent;
158*61046927SAndroid Build Coastguard Worker }
159*61046927SAndroid Build Coastguard Worker 
160*61046927SAndroid Build Coastguard Worker static void
indirect_unbind_context(struct glx_context * gc)161*61046927SAndroid Build Coastguard Worker indirect_unbind_context(struct glx_context *gc)
162*61046927SAndroid Build Coastguard Worker {
163*61046927SAndroid Build Coastguard Worker    Display *dpy = gc->psc->dpy;
164*61046927SAndroid Build Coastguard Worker 
165*61046927SAndroid Build Coastguard Worker    SendMakeCurrentRequest(dpy, None, gc->currentContextTag, None, None, NULL);
166*61046927SAndroid Build Coastguard Worker    gc->currentContextTag = 0;
167*61046927SAndroid Build Coastguard Worker }
168*61046927SAndroid Build Coastguard Worker 
169*61046927SAndroid Build Coastguard Worker static void
indirect_wait_gl(struct glx_context * gc)170*61046927SAndroid Build Coastguard Worker indirect_wait_gl(struct glx_context *gc)
171*61046927SAndroid Build Coastguard Worker {
172*61046927SAndroid Build Coastguard Worker    xGLXWaitGLReq *req;
173*61046927SAndroid Build Coastguard Worker    Display *dpy = gc->currentDpy;
174*61046927SAndroid Build Coastguard Worker 
175*61046927SAndroid Build Coastguard Worker    /* Flush any pending commands out */
176*61046927SAndroid Build Coastguard Worker    __glXFlushRenderBuffer(gc, gc->pc);
177*61046927SAndroid Build Coastguard Worker 
178*61046927SAndroid Build Coastguard Worker    /* Send the glXWaitGL request */
179*61046927SAndroid Build Coastguard Worker    LockDisplay(dpy);
180*61046927SAndroid Build Coastguard Worker    GetReq(GLXWaitGL, req);
181*61046927SAndroid Build Coastguard Worker    req->reqType = gc->majorOpcode;
182*61046927SAndroid Build Coastguard Worker    req->glxCode = X_GLXWaitGL;
183*61046927SAndroid Build Coastguard Worker    req->contextTag = gc->currentContextTag;
184*61046927SAndroid Build Coastguard Worker    UnlockDisplay(dpy);
185*61046927SAndroid Build Coastguard Worker    SyncHandle();
186*61046927SAndroid Build Coastguard Worker }
187*61046927SAndroid Build Coastguard Worker 
188*61046927SAndroid Build Coastguard Worker static void
indirect_wait_x(struct glx_context * gc)189*61046927SAndroid Build Coastguard Worker indirect_wait_x(struct glx_context *gc)
190*61046927SAndroid Build Coastguard Worker {
191*61046927SAndroid Build Coastguard Worker    xGLXWaitXReq *req;
192*61046927SAndroid Build Coastguard Worker    Display *dpy = gc->currentDpy;
193*61046927SAndroid Build Coastguard Worker 
194*61046927SAndroid Build Coastguard Worker    /* Flush any pending commands out */
195*61046927SAndroid Build Coastguard Worker    __glXFlushRenderBuffer(gc, gc->pc);
196*61046927SAndroid Build Coastguard Worker 
197*61046927SAndroid Build Coastguard Worker    LockDisplay(dpy);
198*61046927SAndroid Build Coastguard Worker    GetReq(GLXWaitX, req);
199*61046927SAndroid Build Coastguard Worker    req->reqType = gc->majorOpcode;
200*61046927SAndroid Build Coastguard Worker    req->glxCode = X_GLXWaitX;
201*61046927SAndroid Build Coastguard Worker    req->contextTag = gc->currentContextTag;
202*61046927SAndroid Build Coastguard Worker    UnlockDisplay(dpy);
203*61046927SAndroid Build Coastguard Worker    SyncHandle();
204*61046927SAndroid Build Coastguard Worker }
205*61046927SAndroid Build Coastguard Worker 
206*61046927SAndroid Build Coastguard Worker static const struct glx_context_vtable indirect_context_vtable = {
207*61046927SAndroid Build Coastguard Worker    .destroy             = indirect_destroy_context,
208*61046927SAndroid Build Coastguard Worker    .bind                = indirect_bind_context,
209*61046927SAndroid Build Coastguard Worker    .unbind              = indirect_unbind_context,
210*61046927SAndroid Build Coastguard Worker    .wait_gl             = indirect_wait_gl,
211*61046927SAndroid Build Coastguard Worker    .wait_x              = indirect_wait_x,
212*61046927SAndroid Build Coastguard Worker };
213*61046927SAndroid Build Coastguard Worker 
214*61046927SAndroid Build Coastguard Worker _X_HIDDEN struct glx_context *
indirect_create_context(struct glx_screen * psc,struct glx_config * mode,struct glx_context * shareList,int renderType)215*61046927SAndroid Build Coastguard Worker indirect_create_context(struct glx_screen *psc,
216*61046927SAndroid Build Coastguard Worker          struct glx_config *mode,
217*61046927SAndroid Build Coastguard Worker          struct glx_context *shareList, int renderType)
218*61046927SAndroid Build Coastguard Worker {
219*61046927SAndroid Build Coastguard Worker    unsigned error = 0;
220*61046927SAndroid Build Coastguard Worker    const uint32_t attribs[] = { GLX_RENDER_TYPE, renderType };
221*61046927SAndroid Build Coastguard Worker 
222*61046927SAndroid Build Coastguard Worker    return indirect_create_context_attribs(psc, mode, shareList,
223*61046927SAndroid Build Coastguard Worker                                           1, attribs, &error);
224*61046927SAndroid Build Coastguard Worker }
225*61046927SAndroid Build Coastguard Worker 
226*61046927SAndroid Build Coastguard Worker /**
227*61046927SAndroid Build Coastguard Worker  * \todo Eliminate \c __glXInitVertexArrayState.  Replace it with a new
228*61046927SAndroid Build Coastguard Worker  * function called \c __glXAllocateClientState that allocates the memory and
229*61046927SAndroid Build Coastguard Worker  * does all the initialization (including the pixel pack / unpack).
230*61046927SAndroid Build Coastguard Worker  */
231*61046927SAndroid Build Coastguard Worker _X_HIDDEN struct glx_context *
indirect_create_context_attribs(struct glx_screen * psc,struct glx_config * mode,struct glx_context * shareList,unsigned num_attribs,const uint32_t * attribs,unsigned * error)232*61046927SAndroid Build Coastguard Worker indirect_create_context_attribs(struct glx_screen *psc,
233*61046927SAndroid Build Coastguard Worker             struct glx_config *mode,
234*61046927SAndroid Build Coastguard Worker             struct glx_context *shareList,
235*61046927SAndroid Build Coastguard Worker             unsigned num_attribs,
236*61046927SAndroid Build Coastguard Worker             const uint32_t *attribs,
237*61046927SAndroid Build Coastguard Worker             unsigned *error)
238*61046927SAndroid Build Coastguard Worker {
239*61046927SAndroid Build Coastguard Worker    struct glx_context *gc;
240*61046927SAndroid Build Coastguard Worker    int bufSize;
241*61046927SAndroid Build Coastguard Worker    CARD8 opcode;
242*61046927SAndroid Build Coastguard Worker    __GLXattribute *state;
243*61046927SAndroid Build Coastguard Worker    int i, renderType = GLX_RGBA_TYPE;
244*61046927SAndroid Build Coastguard Worker    uint32_t mask = GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
245*61046927SAndroid Build Coastguard Worker    uint32_t major = 1;
246*61046927SAndroid Build Coastguard Worker    uint32_t minor = 0;
247*61046927SAndroid Build Coastguard Worker 
248*61046927SAndroid Build Coastguard Worker    opcode = __glXSetupForCommand(psc->dpy);
249*61046927SAndroid Build Coastguard Worker    if (!opcode) {
250*61046927SAndroid Build Coastguard Worker       *error = BadImplementation;
251*61046927SAndroid Build Coastguard Worker       return NULL;
252*61046927SAndroid Build Coastguard Worker    }
253*61046927SAndroid Build Coastguard Worker 
254*61046927SAndroid Build Coastguard Worker    for (i = 0; i < num_attribs; i++) {
255*61046927SAndroid Build Coastguard Worker       uint32_t attr = attribs[i*2], val = attribs[i*2 + 1];
256*61046927SAndroid Build Coastguard Worker 
257*61046927SAndroid Build Coastguard Worker       if (attr == GLX_RENDER_TYPE)
258*61046927SAndroid Build Coastguard Worker          renderType = val;
259*61046927SAndroid Build Coastguard Worker       if (attr == GLX_CONTEXT_PROFILE_MASK_ARB)
260*61046927SAndroid Build Coastguard Worker          mask = val;
261*61046927SAndroid Build Coastguard Worker       if (attr == GLX_CONTEXT_MAJOR_VERSION_ARB)
262*61046927SAndroid Build Coastguard Worker          major = val;
263*61046927SAndroid Build Coastguard Worker       if (attr == GLX_CONTEXT_MINOR_VERSION_ARB)
264*61046927SAndroid Build Coastguard Worker          minor = val;
265*61046927SAndroid Build Coastguard Worker    }
266*61046927SAndroid Build Coastguard Worker 
267*61046927SAndroid Build Coastguard Worker    /* We have no indirect support for core or ES contexts, and our compat
268*61046927SAndroid Build Coastguard Worker     * context support is limited to GL 1.4.
269*61046927SAndroid Build Coastguard Worker     */
270*61046927SAndroid Build Coastguard Worker    if (mask != GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB ||
271*61046927SAndroid Build Coastguard Worker        major != 1 ||
272*61046927SAndroid Build Coastguard Worker        minor > 4) {
273*61046927SAndroid Build Coastguard Worker       *error = GLXBadFBConfig;
274*61046927SAndroid Build Coastguard Worker       return NULL;
275*61046927SAndroid Build Coastguard Worker    }
276*61046927SAndroid Build Coastguard Worker 
277*61046927SAndroid Build Coastguard Worker    /* We can't share with a direct context */
278*61046927SAndroid Build Coastguard Worker    if (shareList && shareList->isDirect)
279*61046927SAndroid Build Coastguard Worker       return NULL;
280*61046927SAndroid Build Coastguard Worker 
281*61046927SAndroid Build Coastguard Worker    /* Allocate our context record */
282*61046927SAndroid Build Coastguard Worker    gc = calloc(1, sizeof *gc);
283*61046927SAndroid Build Coastguard Worker    if (!gc) {
284*61046927SAndroid Build Coastguard Worker       *error = BadAlloc;
285*61046927SAndroid Build Coastguard Worker       /* Out of memory */
286*61046927SAndroid Build Coastguard Worker       return NULL;
287*61046927SAndroid Build Coastguard Worker    }
288*61046927SAndroid Build Coastguard Worker 
289*61046927SAndroid Build Coastguard Worker    glx_context_init(gc, psc, mode);
290*61046927SAndroid Build Coastguard Worker    gc->isDirect = GL_FALSE;
291*61046927SAndroid Build Coastguard Worker    gc->vtable = &indirect_context_vtable;
292*61046927SAndroid Build Coastguard Worker    state = calloc(1, sizeof(struct __GLXattributeRec));
293*61046927SAndroid Build Coastguard Worker    gc->renderType = renderType;
294*61046927SAndroid Build Coastguard Worker 
295*61046927SAndroid Build Coastguard Worker    if (state == NULL) {
296*61046927SAndroid Build Coastguard Worker       /* Out of memory */
297*61046927SAndroid Build Coastguard Worker       *error = BadAlloc;
298*61046927SAndroid Build Coastguard Worker       free(gc);
299*61046927SAndroid Build Coastguard Worker       return NULL;
300*61046927SAndroid Build Coastguard Worker    }
301*61046927SAndroid Build Coastguard Worker    gc->client_state_private = state;
302*61046927SAndroid Build Coastguard Worker    state->NoDrawArraysProtocol = debug_get_bool_option("LIBGL_NO_DRAWARRAYS", false);
303*61046927SAndroid Build Coastguard Worker 
304*61046927SAndroid Build Coastguard Worker    /*
305*61046927SAndroid Build Coastguard Worker     ** Create a temporary buffer to hold GLX rendering commands.  The size
306*61046927SAndroid Build Coastguard Worker     ** of the buffer is selected so that the maximum number of GLX rendering
307*61046927SAndroid Build Coastguard Worker     ** commands can fit in a single X packet and still have room in the X
308*61046927SAndroid Build Coastguard Worker     ** packet for the GLXRenderReq header.
309*61046927SAndroid Build Coastguard Worker     */
310*61046927SAndroid Build Coastguard Worker 
311*61046927SAndroid Build Coastguard Worker    bufSize = (XMaxRequestSize(psc->dpy) * 4) - sz_xGLXRenderReq;
312*61046927SAndroid Build Coastguard Worker    gc->buf = malloc(bufSize);
313*61046927SAndroid Build Coastguard Worker    if (!gc->buf) {
314*61046927SAndroid Build Coastguard Worker       *error = BadAlloc;
315*61046927SAndroid Build Coastguard Worker       free(gc->client_state_private);
316*61046927SAndroid Build Coastguard Worker       free(gc);
317*61046927SAndroid Build Coastguard Worker       return NULL;
318*61046927SAndroid Build Coastguard Worker    }
319*61046927SAndroid Build Coastguard Worker    gc->bufSize = bufSize;
320*61046927SAndroid Build Coastguard Worker 
321*61046927SAndroid Build Coastguard Worker    /* Fill in the new context */
322*61046927SAndroid Build Coastguard Worker    gc->renderMode = GL_RENDER;
323*61046927SAndroid Build Coastguard Worker 
324*61046927SAndroid Build Coastguard Worker    state->storePack.alignment = 4;
325*61046927SAndroid Build Coastguard Worker    state->storeUnpack.alignment = 4;
326*61046927SAndroid Build Coastguard Worker 
327*61046927SAndroid Build Coastguard Worker    gc->attributes.stackPointer = &gc->attributes.stack[0];
328*61046927SAndroid Build Coastguard Worker 
329*61046927SAndroid Build Coastguard Worker    gc->pc = gc->buf;
330*61046927SAndroid Build Coastguard Worker    gc->bufEnd = gc->buf + bufSize;
331*61046927SAndroid Build Coastguard Worker    gc->isDirect = GL_FALSE;
332*61046927SAndroid Build Coastguard Worker    if (__glXDebug) {
333*61046927SAndroid Build Coastguard Worker       /*
334*61046927SAndroid Build Coastguard Worker        ** Set limit register so that there will be one command per packet
335*61046927SAndroid Build Coastguard Worker        */
336*61046927SAndroid Build Coastguard Worker       gc->limit = gc->buf;
337*61046927SAndroid Build Coastguard Worker    }
338*61046927SAndroid Build Coastguard Worker    else {
339*61046927SAndroid Build Coastguard Worker       gc->limit = gc->buf + bufSize - __GLX_BUFFER_LIMIT_SIZE;
340*61046927SAndroid Build Coastguard Worker    }
341*61046927SAndroid Build Coastguard Worker    gc->majorOpcode = opcode;
342*61046927SAndroid Build Coastguard Worker 
343*61046927SAndroid Build Coastguard Worker    /*
344*61046927SAndroid Build Coastguard Worker     ** Constrain the maximum drawing command size allowed to be
345*61046927SAndroid Build Coastguard Worker     ** transferred using the X_GLXRender protocol request.  First
346*61046927SAndroid Build Coastguard Worker     ** constrain by a software limit, then constrain by the protocol
347*61046927SAndroid Build Coastguard Worker     ** limit.
348*61046927SAndroid Build Coastguard Worker     */
349*61046927SAndroid Build Coastguard Worker    gc->maxSmallRenderCommandSize = MIN3(bufSize, __GLX_RENDER_CMD_SIZE_LIMIT,
350*61046927SAndroid Build Coastguard Worker                                         __GLX_MAX_RENDER_CMD_SIZE);
351*61046927SAndroid Build Coastguard Worker 
352*61046927SAndroid Build Coastguard Worker 
353*61046927SAndroid Build Coastguard Worker    return gc;
354*61046927SAndroid Build Coastguard Worker }
355*61046927SAndroid Build Coastguard Worker 
356*61046927SAndroid Build Coastguard Worker static const struct glx_screen_vtable indirect_screen_vtable = {
357*61046927SAndroid Build Coastguard Worker    .create_context         = indirect_create_context,
358*61046927SAndroid Build Coastguard Worker    .create_context_attribs = indirect_create_context_attribs,
359*61046927SAndroid Build Coastguard Worker    .query_renderer_integer = NULL,
360*61046927SAndroid Build Coastguard Worker    .query_renderer_string  = NULL,
361*61046927SAndroid Build Coastguard Worker };
362*61046927SAndroid Build Coastguard Worker 
363*61046927SAndroid Build Coastguard Worker _X_HIDDEN struct glx_screen *
indirect_create_screen(int screen,struct glx_display * priv)364*61046927SAndroid Build Coastguard Worker indirect_create_screen(int screen, struct glx_display * priv)
365*61046927SAndroid Build Coastguard Worker {
366*61046927SAndroid Build Coastguard Worker    struct glx_screen *psc;
367*61046927SAndroid Build Coastguard Worker 
368*61046927SAndroid Build Coastguard Worker    psc = calloc(1, sizeof *psc);
369*61046927SAndroid Build Coastguard Worker    if (psc == NULL)
370*61046927SAndroid Build Coastguard Worker       return NULL;
371*61046927SAndroid Build Coastguard Worker 
372*61046927SAndroid Build Coastguard Worker    glx_screen_init(psc, screen, priv);
373*61046927SAndroid Build Coastguard Worker    psc->vtable = &indirect_screen_vtable;
374*61046927SAndroid Build Coastguard Worker 
375*61046927SAndroid Build Coastguard Worker    return psc;
376*61046927SAndroid Build Coastguard Worker }
377*61046927SAndroid Build Coastguard Worker 
378*61046927SAndroid Build Coastguard Worker #endif
379