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