single2swap.c revision 706f2543
1/* 2 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) 3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice including the dates of first publication and 13 * either this permission notice or a reference to 14 * http://oss.sgi.com/projects/FreeB/ 15 * shall be included in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 * SOFTWARE. 24 * 25 * Except as contained in this notice, the name of Silicon Graphics, Inc. 26 * shall not be used in advertising or otherwise to promote the sale, use or 27 * other dealings in this Software without prior written authorization from 28 * Silicon Graphics, Inc. 29 */ 30 31#ifdef HAVE_DIX_CONFIG_H 32#include <dix-config.h> 33#endif 34 35#include "glxserver.h" 36#include "glxutil.h" 37#include "glxext.h" 38#include "indirect_dispatch.h" 39#include "unpack.h" 40#include "glapitable.h" 41#include "glapi.h" 42#include "glthread.h" 43#include "dispatch.h" 44 45int __glXDispSwap_FeedbackBuffer(__GLXclientState *cl, GLbyte *pc) 46{ 47 ClientPtr client = cl->client; 48 GLsizei size; 49 GLenum type; 50 __GLX_DECLARE_SWAP_VARIABLES; 51 __GLXcontext *cx; 52 int error; 53 54 REQUEST_FIXED_SIZE(xGLXSingleReq, 8); 55 56 __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag); 57 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); 58 if (!cx) { 59 return error; 60 } 61 62 pc += __GLX_SINGLE_HDR_SIZE; 63 __GLX_SWAP_INT(pc+0); 64 __GLX_SWAP_INT(pc+4); 65 size = *(GLsizei *)(pc+0); 66 type = *(GLenum *)(pc+4); 67 if (cx->feedbackBufSize < size) { 68 cx->feedbackBuf = (GLfloat *) realloc(cx->feedbackBuf, 69 (size_t) size 70 * __GLX_SIZE_FLOAT32); 71 if (!cx->feedbackBuf) { 72 cl->client->errorValue = size; 73 return BadAlloc; 74 } 75 cx->feedbackBufSize = size; 76 } 77 CALL_FeedbackBuffer( GET_DISPATCH(), (size, type, cx->feedbackBuf) ); 78 __GLX_NOTE_UNFLUSHED_CMDS(cx); 79 return Success; 80} 81 82int __glXDispSwap_SelectBuffer(__GLXclientState *cl, GLbyte *pc) 83{ 84 ClientPtr client = cl->client; 85 __GLXcontext *cx; 86 GLsizei size; 87 __GLX_DECLARE_SWAP_VARIABLES; 88 int error; 89 90 REQUEST_FIXED_SIZE(xGLXSingleReq, 4); 91 92 __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag); 93 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); 94 if (!cx) { 95 return error; 96 } 97 98 pc += __GLX_SINGLE_HDR_SIZE; 99 __GLX_SWAP_INT(pc+0); 100 size = *(GLsizei *)(pc+0); 101 if (cx->selectBufSize < size) { 102 cx->selectBuf = (GLuint *) realloc(cx->selectBuf, 103 (size_t) size 104 * __GLX_SIZE_CARD32); 105 if (!cx->selectBuf) { 106 cl->client->errorValue = size; 107 return BadAlloc; 108 } 109 cx->selectBufSize = size; 110 } 111 CALL_SelectBuffer( GET_DISPATCH(), (size, cx->selectBuf) ); 112 __GLX_NOTE_UNFLUSHED_CMDS(cx); 113 return Success; 114} 115 116int __glXDispSwap_RenderMode(__GLXclientState *cl, GLbyte *pc) 117{ 118 ClientPtr client = cl->client; 119 __GLXcontext *cx; 120 xGLXRenderModeReply reply; 121 GLint nitems=0, retBytes=0, retval, newModeCheck; 122 GLubyte *retBuffer = NULL; 123 GLenum newMode; 124 __GLX_DECLARE_SWAP_VARIABLES; 125 __GLX_DECLARE_SWAP_ARRAY_VARIABLES; 126 int error; 127 128 REQUEST_FIXED_SIZE(xGLXSingleReq, 4); 129 130 __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag); 131 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); 132 if (!cx) { 133 return error; 134 } 135 136 pc += __GLX_SINGLE_HDR_SIZE; 137 __GLX_SWAP_INT(pc); 138 newMode = *(GLenum*) pc; 139 retval = CALL_RenderMode( GET_DISPATCH(), (newMode) ); 140 141 /* Check that render mode worked */ 142 CALL_GetIntegerv( GET_DISPATCH(), (GL_RENDER_MODE, &newModeCheck) ); 143 if (newModeCheck != newMode) { 144 /* Render mode change failed. Bail */ 145 newMode = newModeCheck; 146 goto noChangeAllowed; 147 } 148 149 /* 150 ** Render mode might have still failed if we get here. But in this 151 ** case we can't really tell, nor does it matter. If it did fail, it 152 ** will return 0, and thus we won't send any data across the wire. 153 */ 154 155 switch (cx->renderMode) { 156 case GL_RENDER: 157 cx->renderMode = newMode; 158 break; 159 case GL_FEEDBACK: 160 if (retval < 0) { 161 /* Overflow happened. Copy the entire buffer */ 162 nitems = cx->feedbackBufSize; 163 } else { 164 nitems = retval; 165 } 166 retBytes = nitems * __GLX_SIZE_FLOAT32; 167 retBuffer = (GLubyte*) cx->feedbackBuf; 168 __GLX_SWAP_FLOAT_ARRAY((GLbyte *)retBuffer, nitems); 169 cx->renderMode = newMode; 170 break; 171 case GL_SELECT: 172 if (retval < 0) { 173 /* Overflow happened. Copy the entire buffer */ 174 nitems = cx->selectBufSize; 175 } else { 176 GLuint *bp = cx->selectBuf; 177 GLint i; 178 179 /* 180 ** Figure out how many bytes of data need to be sent. Parse 181 ** the selection buffer to determine this fact as the 182 ** return value is the number of hits, not the number of 183 ** items in the buffer. 184 */ 185 nitems = 0; 186 i = retval; 187 while (--i >= 0) { 188 GLuint n; 189 190 /* Parse select data for this hit */ 191 n = *bp; 192 bp += 3 + n; 193 } 194 nitems = bp - cx->selectBuf; 195 } 196 retBytes = nitems * __GLX_SIZE_CARD32; 197 retBuffer = (GLubyte*) cx->selectBuf; 198 __GLX_SWAP_INT_ARRAY((GLbyte *)retBuffer, nitems); 199 cx->renderMode = newMode; 200 break; 201 } 202 203 /* 204 ** First reply is the number of elements returned in the feedback or 205 ** selection array, as per the API for glRenderMode itself. 206 */ 207 noChangeAllowed:; 208 reply.length = nitems; 209 reply.type = X_Reply; 210 reply.sequenceNumber = client->sequence; 211 reply.retval = retval; 212 reply.size = nitems; 213 reply.newMode = newMode; 214 __GLX_SWAP_SHORT(&reply.sequenceNumber); 215 __GLX_SWAP_INT(&reply.length); 216 __GLX_SWAP_INT(&reply.retval); 217 __GLX_SWAP_INT(&reply.size); 218 __GLX_SWAP_INT(&reply.newMode); 219 WriteToClient(client, sz_xGLXRenderModeReply, (char *)&reply); 220 if (retBytes) { 221 WriteToClient(client, retBytes, (char *)retBuffer); 222 } 223 return Success; 224} 225 226int __glXDispSwap_Flush(__GLXclientState *cl, GLbyte *pc) 227{ 228 ClientPtr client = cl->client; 229 __GLXcontext *cx; 230 int error; 231 __GLX_DECLARE_SWAP_VARIABLES; 232 233 REQUEST_SIZE_MATCH(xGLXSingleReq); 234 235 __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag); 236 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); 237 if (!cx) { 238 return error; 239 } 240 241 CALL_Flush( GET_DISPATCH(), () ); 242 __GLX_NOTE_FLUSHED_CMDS(cx); 243 return Success; 244} 245 246int __glXDispSwap_Finish(__GLXclientState *cl, GLbyte *pc) 247{ 248 ClientPtr client = cl->client; 249 __GLXcontext *cx; 250 int error; 251 __GLX_DECLARE_SWAP_VARIABLES; 252 253 REQUEST_SIZE_MATCH(xGLXSingleReq); 254 255 __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag); 256 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); 257 if (!cx) { 258 return error; 259 } 260 261 /* Do a local glFinish */ 262 CALL_Finish( GET_DISPATCH(), () ); 263 __GLX_NOTE_FLUSHED_CMDS(cx); 264 265 /* Send empty reply packet to indicate finish is finished */ 266 __GLX_BEGIN_REPLY(0); 267 __GLX_PUT_RETVAL(0); 268 __GLX_SWAP_REPLY_HEADER(); 269 __GLX_SEND_HEADER(); 270 271 return Success; 272} 273 274int __glXDispSwap_GetString(__GLXclientState *cl, GLbyte *pc) 275{ 276 return DoGetString(cl, pc, GL_TRUE); 277} 278