indirect_glx.c revision 01e04c3f
13464ebd5Sriastradh/* 23464ebd5Sriastradh * Copyright © 2010 Intel Corporation 33464ebd5Sriastradh * 43464ebd5Sriastradh * Permission is hereby granted, free of charge, to any person obtaining a 53464ebd5Sriastradh * copy of this software and associated documentation files (the "Soft- 63464ebd5Sriastradh * ware"), to deal in the Software without restriction, including without 73464ebd5Sriastradh * limitation the rights to use, copy, modify, merge, publish, distribute, 83464ebd5Sriastradh * and/or sell copies of the Software, and to permit persons to whom the 93464ebd5Sriastradh * Software is furnished to do so, provided that the above copyright 103464ebd5Sriastradh * notice(s) and this permission notice appear in all copies of the Soft- 113464ebd5Sriastradh * ware and that both the above copyright notice(s) and this permission 123464ebd5Sriastradh * notice appear in supporting documentation. 133464ebd5Sriastradh * 143464ebd5Sriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 153464ebd5Sriastradh * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- 163464ebd5Sriastradh * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY 173464ebd5Sriastradh * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN 183464ebd5Sriastradh * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- 193464ebd5Sriastradh * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 203464ebd5Sriastradh * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 213464ebd5Sriastradh * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- 223464ebd5Sriastradh * MANCE OF THIS SOFTWARE. 233464ebd5Sriastradh * 243464ebd5Sriastradh * Except as contained in this notice, the name of a copyright holder shall 253464ebd5Sriastradh * not be used in advertising or otherwise to promote the sale, use or 263464ebd5Sriastradh * other dealings in this Software without prior written authorization of 273464ebd5Sriastradh * the copyright holder. 283464ebd5Sriastradh * 293464ebd5Sriastradh * Authors: 303464ebd5Sriastradh * Kristian Høgsberg (krh@bitplanet.net) 313464ebd5Sriastradh */ 323464ebd5Sriastradh 3301e04c3fSmrg#include <stdbool.h> 3401e04c3fSmrg 353464ebd5Sriastradh#include "glapi.h" 363464ebd5Sriastradh#include "glxclient.h" 373464ebd5Sriastradh 3801e04c3fSmrg#include "util/debug.h" 3901e04c3fSmrg 40af69d88dSmrg#ifndef GLX_USE_APPLEGL 41af69d88dSmrg 423464ebd5Sriastradhextern struct _glapi_table *__glXNewIndirectAPI(void); 433464ebd5Sriastradh 443464ebd5Sriastradh/* 453464ebd5Sriastradh** All indirect rendering contexts will share the same indirect dispatch table. 463464ebd5Sriastradh*/ 473464ebd5Sriastradhstatic struct _glapi_table *IndirectAPI = NULL; 483464ebd5Sriastradh 493464ebd5Sriastradhstatic void 503464ebd5Sriastradhindirect_destroy_context(struct glx_context *gc) 513464ebd5Sriastradh{ 523464ebd5Sriastradh __glXFreeVertexArrayState(gc); 533464ebd5Sriastradh 54af69d88dSmrg free((char *) gc->vendor); 55af69d88dSmrg free((char *) gc->renderer); 56af69d88dSmrg free((char *) gc->version); 57af69d88dSmrg free((char *) gc->extensions); 583464ebd5Sriastradh __glFreeAttributeState(gc); 59af69d88dSmrg free((char *) gc->buf); 60af69d88dSmrg free((char *) gc->client_state_private); 61af69d88dSmrg free((char *) gc); 623464ebd5Sriastradh} 633464ebd5Sriastradh 643464ebd5Sriastradhstatic Bool 6501e04c3fSmrgSendMakeCurrentRequest(Display * dpy, GLXContextID gc_id, 6601e04c3fSmrg GLXContextTag gc_tag, GLXDrawable draw, 6701e04c3fSmrg GLXDrawable read, GLXContextTag *out_tag) 683464ebd5Sriastradh{ 69af69d88dSmrg xGLXMakeCurrentReply reply; 703464ebd5Sriastradh Bool ret; 7101e04c3fSmrg int opcode = __glXSetupForCommand(dpy); 723464ebd5Sriastradh 733464ebd5Sriastradh LockDisplay(dpy); 743464ebd5Sriastradh 753464ebd5Sriastradh if (draw == read) { 763464ebd5Sriastradh xGLXMakeCurrentReq *req; 773464ebd5Sriastradh 783464ebd5Sriastradh GetReq(GLXMakeCurrent, req); 793464ebd5Sriastradh req->reqType = opcode; 803464ebd5Sriastradh req->glxCode = X_GLXMakeCurrent; 813464ebd5Sriastradh req->drawable = draw; 823464ebd5Sriastradh req->context = gc_id; 833464ebd5Sriastradh req->oldContextTag = gc_tag; 843464ebd5Sriastradh } 853464ebd5Sriastradh else { 863464ebd5Sriastradh struct glx_display *priv = __glXInitialize(dpy); 873464ebd5Sriastradh 883464ebd5Sriastradh /* If the server can support the GLX 1.3 version, we should 893464ebd5Sriastradh * perfer that. Not only that, some servers support GLX 1.3 but 903464ebd5Sriastradh * not the SGI extension. 913464ebd5Sriastradh */ 923464ebd5Sriastradh 933464ebd5Sriastradh if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) { 943464ebd5Sriastradh xGLXMakeContextCurrentReq *req; 953464ebd5Sriastradh 963464ebd5Sriastradh GetReq(GLXMakeContextCurrent, req); 973464ebd5Sriastradh req->reqType = opcode; 983464ebd5Sriastradh req->glxCode = X_GLXMakeContextCurrent; 993464ebd5Sriastradh req->drawable = draw; 1003464ebd5Sriastradh req->readdrawable = read; 1013464ebd5Sriastradh req->context = gc_id; 1023464ebd5Sriastradh req->oldContextTag = gc_tag; 1033464ebd5Sriastradh } 1043464ebd5Sriastradh else { 1053464ebd5Sriastradh xGLXVendorPrivateWithReplyReq *vpreq; 1063464ebd5Sriastradh xGLXMakeCurrentReadSGIReq *req; 1073464ebd5Sriastradh 1083464ebd5Sriastradh GetReqExtra(GLXVendorPrivateWithReply, 1093464ebd5Sriastradh sz_xGLXMakeCurrentReadSGIReq - 1103464ebd5Sriastradh sz_xGLXVendorPrivateWithReplyReq, vpreq); 1113464ebd5Sriastradh req = (xGLXMakeCurrentReadSGIReq *) vpreq; 1123464ebd5Sriastradh req->reqType = opcode; 1133464ebd5Sriastradh req->glxCode = X_GLXVendorPrivateWithReply; 1143464ebd5Sriastradh req->vendorCode = X_GLXvop_MakeCurrentReadSGI; 1153464ebd5Sriastradh req->drawable = draw; 1163464ebd5Sriastradh req->readable = read; 1173464ebd5Sriastradh req->context = gc_id; 1183464ebd5Sriastradh req->oldContextTag = gc_tag; 1193464ebd5Sriastradh } 1203464ebd5Sriastradh } 1213464ebd5Sriastradh 122af69d88dSmrg ret = _XReply(dpy, (xReply *) &reply, 0, False); 123af69d88dSmrg 124af69d88dSmrg if (out_tag) 125af69d88dSmrg *out_tag = reply.contextTag; 1263464ebd5Sriastradh 1273464ebd5Sriastradh UnlockDisplay(dpy); 1283464ebd5Sriastradh SyncHandle(); 1293464ebd5Sriastradh 1303464ebd5Sriastradh return ret; 1313464ebd5Sriastradh} 1323464ebd5Sriastradh 1333464ebd5Sriastradhstatic int 1343464ebd5Sriastradhindirect_bind_context(struct glx_context *gc, struct glx_context *old, 1353464ebd5Sriastradh GLXDrawable draw, GLXDrawable read) 1363464ebd5Sriastradh{ 1373464ebd5Sriastradh GLXContextTag tag; 1383464ebd5Sriastradh Display *dpy = gc->psc->dpy; 139af69d88dSmrg Bool sent; 1403464ebd5Sriastradh 1413464ebd5Sriastradh if (old != &dummyContext && !old->isDirect && old->psc->dpy == dpy) { 1423464ebd5Sriastradh tag = old->currentContextTag; 1433464ebd5Sriastradh old->currentContextTag = 0; 1443464ebd5Sriastradh } else { 1453464ebd5Sriastradh tag = 0; 1463464ebd5Sriastradh } 1473464ebd5Sriastradh 14801e04c3fSmrg sent = SendMakeCurrentRequest(dpy, gc->xid, tag, draw, read, 149af69d88dSmrg &gc->currentContextTag); 1503464ebd5Sriastradh 1513464ebd5Sriastradh if (!IndirectAPI) 1523464ebd5Sriastradh IndirectAPI = __glXNewIndirectAPI(); 1533464ebd5Sriastradh _glapi_set_dispatch(IndirectAPI); 1543464ebd5Sriastradh 155af69d88dSmrg return !sent; 1563464ebd5Sriastradh} 1573464ebd5Sriastradh 1583464ebd5Sriastradhstatic void 1593464ebd5Sriastradhindirect_unbind_context(struct glx_context *gc, struct glx_context *new) 1603464ebd5Sriastradh{ 1613464ebd5Sriastradh Display *dpy = gc->psc->dpy; 1623464ebd5Sriastradh 1633464ebd5Sriastradh if (gc == new) 1643464ebd5Sriastradh return; 1653464ebd5Sriastradh 16601e04c3fSmrg /* We are either switching to no context, away from an indirect 1673464ebd5Sriastradh * context to a direct context or from one dpy to another and have 1683464ebd5Sriastradh * to send a request to the dpy to unbind the previous context. 1693464ebd5Sriastradh */ 1703464ebd5Sriastradh if (!new || new->isDirect || new->psc->dpy != dpy) { 17101e04c3fSmrg SendMakeCurrentRequest(dpy, None, gc->currentContextTag, None, None, 17201e04c3fSmrg NULL); 1733464ebd5Sriastradh gc->currentContextTag = 0; 1743464ebd5Sriastradh } 1753464ebd5Sriastradh} 1763464ebd5Sriastradh 1773464ebd5Sriastradhstatic void 1783464ebd5Sriastradhindirect_wait_gl(struct glx_context *gc) 1793464ebd5Sriastradh{ 1803464ebd5Sriastradh xGLXWaitGLReq *req; 1813464ebd5Sriastradh Display *dpy = gc->currentDpy; 1823464ebd5Sriastradh 1833464ebd5Sriastradh /* Flush any pending commands out */ 1843464ebd5Sriastradh __glXFlushRenderBuffer(gc, gc->pc); 1853464ebd5Sriastradh 1863464ebd5Sriastradh /* Send the glXWaitGL request */ 1873464ebd5Sriastradh LockDisplay(dpy); 1883464ebd5Sriastradh GetReq(GLXWaitGL, req); 1893464ebd5Sriastradh req->reqType = gc->majorOpcode; 1903464ebd5Sriastradh req->glxCode = X_GLXWaitGL; 1913464ebd5Sriastradh req->contextTag = gc->currentContextTag; 1923464ebd5Sriastradh UnlockDisplay(dpy); 1933464ebd5Sriastradh SyncHandle(); 1943464ebd5Sriastradh} 1953464ebd5Sriastradh 1963464ebd5Sriastradhstatic void 1973464ebd5Sriastradhindirect_wait_x(struct glx_context *gc) 1983464ebd5Sriastradh{ 1993464ebd5Sriastradh xGLXWaitXReq *req; 2003464ebd5Sriastradh Display *dpy = gc->currentDpy; 2013464ebd5Sriastradh 2023464ebd5Sriastradh /* Flush any pending commands out */ 2033464ebd5Sriastradh __glXFlushRenderBuffer(gc, gc->pc); 2043464ebd5Sriastradh 2053464ebd5Sriastradh LockDisplay(dpy); 2063464ebd5Sriastradh GetReq(GLXWaitX, req); 2073464ebd5Sriastradh req->reqType = gc->majorOpcode; 2083464ebd5Sriastradh req->glxCode = X_GLXWaitX; 2093464ebd5Sriastradh req->contextTag = gc->currentContextTag; 2103464ebd5Sriastradh UnlockDisplay(dpy); 2113464ebd5Sriastradh SyncHandle(); 2123464ebd5Sriastradh} 2133464ebd5Sriastradh 2143464ebd5Sriastradhstatic void 2153464ebd5Sriastradhindirect_use_x_font(struct glx_context *gc, 2163464ebd5Sriastradh Font font, int first, int count, int listBase) 2173464ebd5Sriastradh{ 2183464ebd5Sriastradh xGLXUseXFontReq *req; 2193464ebd5Sriastradh Display *dpy = gc->currentDpy; 2203464ebd5Sriastradh 2213464ebd5Sriastradh /* Flush any pending commands out */ 2223464ebd5Sriastradh __glXFlushRenderBuffer(gc, gc->pc); 2233464ebd5Sriastradh 2243464ebd5Sriastradh /* Send the glXUseFont request */ 2253464ebd5Sriastradh LockDisplay(dpy); 2263464ebd5Sriastradh GetReq(GLXUseXFont, req); 2273464ebd5Sriastradh req->reqType = gc->majorOpcode; 2283464ebd5Sriastradh req->glxCode = X_GLXUseXFont; 2293464ebd5Sriastradh req->contextTag = gc->currentContextTag; 2303464ebd5Sriastradh req->font = font; 2313464ebd5Sriastradh req->first = first; 2323464ebd5Sriastradh req->count = count; 2333464ebd5Sriastradh req->listBase = listBase; 2343464ebd5Sriastradh UnlockDisplay(dpy); 2353464ebd5Sriastradh SyncHandle(); 2363464ebd5Sriastradh} 2373464ebd5Sriastradh 2383464ebd5Sriastradhstatic void 2393464ebd5Sriastradhindirect_bind_tex_image(Display * dpy, 2403464ebd5Sriastradh GLXDrawable drawable, 2413464ebd5Sriastradh int buffer, const int *attrib_list) 2423464ebd5Sriastradh{ 2433464ebd5Sriastradh xGLXVendorPrivateReq *req; 2443464ebd5Sriastradh struct glx_context *gc = __glXGetCurrentContext(); 2453464ebd5Sriastradh CARD32 *drawable_ptr; 2463464ebd5Sriastradh INT32 *buffer_ptr; 2473464ebd5Sriastradh CARD32 *num_attrib_ptr; 2483464ebd5Sriastradh CARD32 *attrib_ptr; 2493464ebd5Sriastradh CARD8 opcode; 2503464ebd5Sriastradh unsigned int i; 2513464ebd5Sriastradh 2523464ebd5Sriastradh i = 0; 2533464ebd5Sriastradh if (attrib_list) { 2543464ebd5Sriastradh while (attrib_list[i * 2] != None) 2553464ebd5Sriastradh i++; 2563464ebd5Sriastradh } 2573464ebd5Sriastradh 2583464ebd5Sriastradh opcode = __glXSetupForCommand(dpy); 2593464ebd5Sriastradh if (!opcode) 2603464ebd5Sriastradh return; 2613464ebd5Sriastradh 2623464ebd5Sriastradh LockDisplay(dpy); 2633464ebd5Sriastradh GetReqExtra(GLXVendorPrivate, 12 + 8 * i, req); 2643464ebd5Sriastradh req->reqType = opcode; 2653464ebd5Sriastradh req->glxCode = X_GLXVendorPrivate; 2663464ebd5Sriastradh req->vendorCode = X_GLXvop_BindTexImageEXT; 2673464ebd5Sriastradh req->contextTag = gc->currentContextTag; 2683464ebd5Sriastradh 2693464ebd5Sriastradh drawable_ptr = (CARD32 *) (req + 1); 2703464ebd5Sriastradh buffer_ptr = (INT32 *) (drawable_ptr + 1); 2713464ebd5Sriastradh num_attrib_ptr = (CARD32 *) (buffer_ptr + 1); 2723464ebd5Sriastradh attrib_ptr = (CARD32 *) (num_attrib_ptr + 1); 2733464ebd5Sriastradh 2743464ebd5Sriastradh *drawable_ptr = drawable; 2753464ebd5Sriastradh *buffer_ptr = buffer; 2763464ebd5Sriastradh *num_attrib_ptr = (CARD32) i; 2773464ebd5Sriastradh 2783464ebd5Sriastradh i = 0; 2793464ebd5Sriastradh if (attrib_list) { 2803464ebd5Sriastradh while (attrib_list[i * 2] != None) { 2813464ebd5Sriastradh *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 0]; 2823464ebd5Sriastradh *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 1]; 2833464ebd5Sriastradh i++; 2843464ebd5Sriastradh } 2853464ebd5Sriastradh } 2863464ebd5Sriastradh 2873464ebd5Sriastradh UnlockDisplay(dpy); 2883464ebd5Sriastradh SyncHandle(); 2893464ebd5Sriastradh} 2903464ebd5Sriastradh 2913464ebd5Sriastradhstatic void 2923464ebd5Sriastradhindirect_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer) 2933464ebd5Sriastradh{ 2943464ebd5Sriastradh xGLXVendorPrivateReq *req; 2953464ebd5Sriastradh struct glx_context *gc = __glXGetCurrentContext(); 2963464ebd5Sriastradh CARD32 *drawable_ptr; 2973464ebd5Sriastradh INT32 *buffer_ptr; 2983464ebd5Sriastradh CARD8 opcode; 2993464ebd5Sriastradh 3003464ebd5Sriastradh opcode = __glXSetupForCommand(dpy); 3013464ebd5Sriastradh if (!opcode) 3023464ebd5Sriastradh return; 3033464ebd5Sriastradh 3043464ebd5Sriastradh LockDisplay(dpy); 3053464ebd5Sriastradh GetReqExtra(GLXVendorPrivate, sizeof(CARD32) + sizeof(INT32), req); 3063464ebd5Sriastradh req->reqType = opcode; 3073464ebd5Sriastradh req->glxCode = X_GLXVendorPrivate; 3083464ebd5Sriastradh req->vendorCode = X_GLXvop_ReleaseTexImageEXT; 3093464ebd5Sriastradh req->contextTag = gc->currentContextTag; 3103464ebd5Sriastradh 3113464ebd5Sriastradh drawable_ptr = (CARD32 *) (req + 1); 3123464ebd5Sriastradh buffer_ptr = (INT32 *) (drawable_ptr + 1); 3133464ebd5Sriastradh 3143464ebd5Sriastradh *drawable_ptr = drawable; 3153464ebd5Sriastradh *buffer_ptr = buffer; 3163464ebd5Sriastradh 3173464ebd5Sriastradh UnlockDisplay(dpy); 3183464ebd5Sriastradh SyncHandle(); 3193464ebd5Sriastradh} 3203464ebd5Sriastradh 3213464ebd5Sriastradhstatic const struct glx_context_vtable indirect_context_vtable = { 322af69d88dSmrg .destroy = indirect_destroy_context, 323af69d88dSmrg .bind = indirect_bind_context, 324af69d88dSmrg .unbind = indirect_unbind_context, 325af69d88dSmrg .wait_gl = indirect_wait_gl, 326af69d88dSmrg .wait_x = indirect_wait_x, 327af69d88dSmrg .use_x_font = indirect_use_x_font, 328af69d88dSmrg .bind_tex_image = indirect_bind_tex_image, 329af69d88dSmrg .release_tex_image = indirect_release_tex_image, 330af69d88dSmrg .get_proc_address = NULL, 3313464ebd5Sriastradh}; 3323464ebd5Sriastradh 3333464ebd5Sriastradh/** 3343464ebd5Sriastradh * \todo Eliminate \c __glXInitVertexArrayState. Replace it with a new 3353464ebd5Sriastradh * function called \c __glXAllocateClientState that allocates the memory and 3363464ebd5Sriastradh * does all the initialization (including the pixel pack / unpack). 337af69d88dSmrg * 338af69d88dSmrg * \note 339af69d88dSmrg * This function is \b not the place to validate the context creation 340af69d88dSmrg * parameters. It is just the allocator for the \c glx_context. 3413464ebd5Sriastradh */ 3423464ebd5Sriastradh_X_HIDDEN struct glx_context * 3433464ebd5Sriastradhindirect_create_context(struct glx_screen *psc, 3443464ebd5Sriastradh struct glx_config *mode, 3453464ebd5Sriastradh struct glx_context *shareList, int renderType) 3463464ebd5Sriastradh{ 3473464ebd5Sriastradh struct glx_context *gc; 3483464ebd5Sriastradh int bufSize; 3493464ebd5Sriastradh CARD8 opcode; 3503464ebd5Sriastradh __GLXattribute *state; 3513464ebd5Sriastradh 3523464ebd5Sriastradh opcode = __glXSetupForCommand(psc->dpy); 3533464ebd5Sriastradh if (!opcode) { 3543464ebd5Sriastradh return NULL; 3553464ebd5Sriastradh } 3563464ebd5Sriastradh 3573464ebd5Sriastradh /* Allocate our context record */ 358af69d88dSmrg gc = calloc(1, sizeof *gc); 3593464ebd5Sriastradh if (!gc) { 3603464ebd5Sriastradh /* Out of memory */ 3613464ebd5Sriastradh return NULL; 3623464ebd5Sriastradh } 3633464ebd5Sriastradh 3643464ebd5Sriastradh glx_context_init(gc, psc, mode); 3653464ebd5Sriastradh gc->isDirect = GL_FALSE; 3663464ebd5Sriastradh gc->vtable = &indirect_context_vtable; 367af69d88dSmrg state = calloc(1, sizeof(struct __GLXattributeRec)); 368af69d88dSmrg gc->renderType = renderType; 369af69d88dSmrg 3703464ebd5Sriastradh if (state == NULL) { 3713464ebd5Sriastradh /* Out of memory */ 372af69d88dSmrg free(gc); 3733464ebd5Sriastradh return NULL; 3743464ebd5Sriastradh } 3753464ebd5Sriastradh gc->client_state_private = state; 37601e04c3fSmrg state->NoDrawArraysProtocol = env_var_as_boolean("LIBGL_NO_DRAWARRAYS", false); 3773464ebd5Sriastradh 3783464ebd5Sriastradh /* 3793464ebd5Sriastradh ** Create a temporary buffer to hold GLX rendering commands. The size 3803464ebd5Sriastradh ** of the buffer is selected so that the maximum number of GLX rendering 3813464ebd5Sriastradh ** commands can fit in a single X packet and still have room in the X 3823464ebd5Sriastradh ** packet for the GLXRenderReq header. 3833464ebd5Sriastradh */ 3843464ebd5Sriastradh 3853464ebd5Sriastradh bufSize = (XMaxRequestSize(psc->dpy) * 4) - sz_xGLXRenderReq; 386af69d88dSmrg gc->buf = malloc(bufSize); 3873464ebd5Sriastradh if (!gc->buf) { 388af69d88dSmrg free(gc->client_state_private); 389af69d88dSmrg free(gc); 3903464ebd5Sriastradh return NULL; 3913464ebd5Sriastradh } 3923464ebd5Sriastradh gc->bufSize = bufSize; 3933464ebd5Sriastradh 3943464ebd5Sriastradh /* Fill in the new context */ 3953464ebd5Sriastradh gc->renderMode = GL_RENDER; 3963464ebd5Sriastradh 3973464ebd5Sriastradh state->storePack.alignment = 4; 3983464ebd5Sriastradh state->storeUnpack.alignment = 4; 3993464ebd5Sriastradh 4003464ebd5Sriastradh gc->attributes.stackPointer = &gc->attributes.stack[0]; 4013464ebd5Sriastradh 4023464ebd5Sriastradh /* 4033464ebd5Sriastradh ** PERFORMANCE NOTE: A mode dependent fill image can speed things up. 4043464ebd5Sriastradh */ 4053464ebd5Sriastradh gc->fillImage = __glFillImage; 4063464ebd5Sriastradh gc->pc = gc->buf; 4073464ebd5Sriastradh gc->bufEnd = gc->buf + bufSize; 4083464ebd5Sriastradh gc->isDirect = GL_FALSE; 4093464ebd5Sriastradh if (__glXDebug) { 4103464ebd5Sriastradh /* 4113464ebd5Sriastradh ** Set limit register so that there will be one command per packet 4123464ebd5Sriastradh */ 4133464ebd5Sriastradh gc->limit = gc->buf; 4143464ebd5Sriastradh } 4153464ebd5Sriastradh else { 4163464ebd5Sriastradh gc->limit = gc->buf + bufSize - __GLX_BUFFER_LIMIT_SIZE; 4173464ebd5Sriastradh } 4183464ebd5Sriastradh gc->majorOpcode = opcode; 4193464ebd5Sriastradh 4203464ebd5Sriastradh /* 4213464ebd5Sriastradh ** Constrain the maximum drawing command size allowed to be 4223464ebd5Sriastradh ** transfered using the X_GLXRender protocol request. First 4233464ebd5Sriastradh ** constrain by a software limit, then constrain by the protocl 4243464ebd5Sriastradh ** limit. 4253464ebd5Sriastradh */ 4263464ebd5Sriastradh if (bufSize > __GLX_RENDER_CMD_SIZE_LIMIT) { 4273464ebd5Sriastradh bufSize = __GLX_RENDER_CMD_SIZE_LIMIT; 4283464ebd5Sriastradh } 4293464ebd5Sriastradh if (bufSize > __GLX_MAX_RENDER_CMD_SIZE) { 4303464ebd5Sriastradh bufSize = __GLX_MAX_RENDER_CMD_SIZE; 4313464ebd5Sriastradh } 4323464ebd5Sriastradh gc->maxSmallRenderCommandSize = bufSize; 4333464ebd5Sriastradh 4343464ebd5Sriastradh 4353464ebd5Sriastradh return gc; 4363464ebd5Sriastradh} 4373464ebd5Sriastradh 438af69d88dSmrg_X_HIDDEN struct glx_context * 439af69d88dSmrgindirect_create_context_attribs(struct glx_screen *base, 440af69d88dSmrg struct glx_config *config_base, 441af69d88dSmrg struct glx_context *shareList, 442af69d88dSmrg unsigned num_attribs, 443af69d88dSmrg const uint32_t *attribs, 444af69d88dSmrg unsigned *error) 445af69d88dSmrg{ 446af69d88dSmrg int renderType = GLX_RGBA_TYPE; 447af69d88dSmrg unsigned i; 448af69d88dSmrg 449af69d88dSmrg /* The error parameter is only used on the server so that correct GLX 450af69d88dSmrg * protocol errors can be generated. On the client, it can be ignored. 451af69d88dSmrg */ 452af69d88dSmrg (void) error; 453af69d88dSmrg 454af69d88dSmrg /* All of the attribute validation for indirect contexts is handled on the 455af69d88dSmrg * server, so there's not much to do here. Still, we need to parse the 456af69d88dSmrg * attributes to correctly set renderType. 457af69d88dSmrg */ 458af69d88dSmrg for (i = 0; i < num_attribs; i++) { 459af69d88dSmrg if (attribs[i * 2] == GLX_RENDER_TYPE) 460af69d88dSmrg renderType = attribs[i * 2 + 1]; 461af69d88dSmrg } 462af69d88dSmrg 463af69d88dSmrg return indirect_create_context(base, config_base, shareList, renderType); 464af69d88dSmrg} 465af69d88dSmrg 466af69d88dSmrgstatic const struct glx_screen_vtable indirect_screen_vtable = { 467af69d88dSmrg .create_context = indirect_create_context, 468af69d88dSmrg .create_context_attribs = indirect_create_context_attribs, 469af69d88dSmrg .query_renderer_integer = NULL, 470af69d88dSmrg .query_renderer_string = NULL, 4713464ebd5Sriastradh}; 4723464ebd5Sriastradh 4733464ebd5Sriastradh_X_HIDDEN struct glx_screen * 4743464ebd5Sriastradhindirect_create_screen(int screen, struct glx_display * priv) 4753464ebd5Sriastradh{ 4763464ebd5Sriastradh struct glx_screen *psc; 4773464ebd5Sriastradh 478af69d88dSmrg psc = calloc(1, sizeof *psc); 4793464ebd5Sriastradh if (psc == NULL) 4803464ebd5Sriastradh return NULL; 4813464ebd5Sriastradh 4823464ebd5Sriastradh glx_screen_init(psc, screen, priv); 4833464ebd5Sriastradh psc->vtable = &indirect_screen_vtable; 4843464ebd5Sriastradh 4853464ebd5Sriastradh return psc; 4863464ebd5Sriastradh} 487af69d88dSmrg 488af69d88dSmrg#endif 489