single2swap.c revision 7e31ba66
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 41int 42__glXDispSwap_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc) 43{ 44 ClientPtr client = cl->client; 45 GLsizei size; 46 GLenum type; 47 48 __GLX_DECLARE_SWAP_VARIABLES; 49 __GLXcontext *cx; 50 int error; 51 52 REQUEST_FIXED_SIZE(xGLXSingleReq, 8); 53 54 __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); 55 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); 56 if (!cx) { 57 return error; 58 } 59 60 pc += __GLX_SINGLE_HDR_SIZE; 61 __GLX_SWAP_INT(pc + 0); 62 __GLX_SWAP_INT(pc + 4); 63 size = *(GLsizei *) (pc + 0); 64 type = *(GLenum *) (pc + 4); 65 if (cx->feedbackBufSize < size) { 66 cx->feedbackBuf = reallocarray(cx->feedbackBuf, 67 (size_t) size, __GLX_SIZE_FLOAT32); 68 if (!cx->feedbackBuf) { 69 cl->client->errorValue = size; 70 return BadAlloc; 71 } 72 cx->feedbackBufSize = size; 73 } 74 glFeedbackBuffer(size, type, cx->feedbackBuf); 75 return Success; 76} 77 78int 79__glXDispSwap_SelectBuffer(__GLXclientState * cl, GLbyte * pc) 80{ 81 ClientPtr client = cl->client; 82 __GLXcontext *cx; 83 GLsizei size; 84 85 __GLX_DECLARE_SWAP_VARIABLES; 86 int error; 87 88 REQUEST_FIXED_SIZE(xGLXSingleReq, 4); 89 90 __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); 91 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); 92 if (!cx) { 93 return error; 94 } 95 96 pc += __GLX_SINGLE_HDR_SIZE; 97 __GLX_SWAP_INT(pc + 0); 98 size = *(GLsizei *) (pc + 0); 99 if (cx->selectBufSize < size) { 100 cx->selectBuf = reallocarray(cx->selectBuf, 101 (size_t) size, __GLX_SIZE_CARD32); 102 if (!cx->selectBuf) { 103 cl->client->errorValue = size; 104 return BadAlloc; 105 } 106 cx->selectBufSize = size; 107 } 108 glSelectBuffer(size, cx->selectBuf); 109 return Success; 110} 111 112int 113__glXDispSwap_RenderMode(__GLXclientState * cl, GLbyte * pc) 114{ 115 ClientPtr client = cl->client; 116 __GLXcontext *cx; 117 xGLXRenderModeReply reply; 118 GLint nitems = 0, retBytes = 0, retval, newModeCheck; 119 GLubyte *retBuffer = NULL; 120 GLenum newMode; 121 122 __GLX_DECLARE_SWAP_VARIABLES; 123 __GLX_DECLARE_SWAP_ARRAY_VARIABLES; 124 int error; 125 126 REQUEST_FIXED_SIZE(xGLXSingleReq, 4); 127 128 __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); 129 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); 130 if (!cx) { 131 return error; 132 } 133 134 pc += __GLX_SINGLE_HDR_SIZE; 135 __GLX_SWAP_INT(pc); 136 newMode = *(GLenum *) pc; 137 retval = glRenderMode(newMode); 138 139 /* Check that render mode worked */ 140 glGetIntegerv(GL_RENDER_MODE, &newModeCheck); 141 if (newModeCheck != newMode) { 142 /* Render mode change failed. Bail */ 143 newMode = newModeCheck; 144 goto noChangeAllowed; 145 } 146 147 /* 148 ** Render mode might have still failed if we get here. But in this 149 ** case we can't really tell, nor does it matter. If it did fail, it 150 ** will return 0, and thus we won't send any data across the wire. 151 */ 152 153 switch (cx->renderMode) { 154 case GL_RENDER: 155 cx->renderMode = newMode; 156 break; 157 case GL_FEEDBACK: 158 if (retval < 0) { 159 /* Overflow happened. Copy the entire buffer */ 160 nitems = cx->feedbackBufSize; 161 } 162 else { 163 nitems = retval; 164 } 165 retBytes = nitems * __GLX_SIZE_FLOAT32; 166 retBuffer = (GLubyte *) cx->feedbackBuf; 167 __GLX_SWAP_FLOAT_ARRAY((GLbyte *) retBuffer, nitems); 168 cx->renderMode = newMode; 169 break; 170 case GL_SELECT: 171 if (retval < 0) { 172 /* Overflow happened. Copy the entire buffer */ 173 nitems = cx->selectBufSize; 174 } 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 = (xGLXRenderModeReply) { 209 .type = X_Reply, 210 .sequenceNumber = client->sequence, 211 .length = nitems, 212 .retval = retval, 213 .size = nitems, 214 .newMode = newMode 215 }; 216 __GLX_SWAP_SHORT(&reply.sequenceNumber); 217 __GLX_SWAP_INT(&reply.length); 218 __GLX_SWAP_INT(&reply.retval); 219 __GLX_SWAP_INT(&reply.size); 220 __GLX_SWAP_INT(&reply.newMode); 221 WriteToClient(client, sz_xGLXRenderModeReply, &reply); 222 if (retBytes) { 223 WriteToClient(client, retBytes, retBuffer); 224 } 225 return Success; 226} 227 228int 229__glXDispSwap_Flush(__GLXclientState * cl, GLbyte * pc) 230{ 231 ClientPtr client = cl->client; 232 __GLXcontext *cx; 233 int error; 234 235 __GLX_DECLARE_SWAP_VARIABLES; 236 237 REQUEST_SIZE_MATCH(xGLXSingleReq); 238 239 __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); 240 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); 241 if (!cx) { 242 return error; 243 } 244 245 glFlush(); 246 return Success; 247} 248 249int 250__glXDispSwap_Finish(__GLXclientState * cl, GLbyte * pc) 251{ 252 ClientPtr client = cl->client; 253 __GLXcontext *cx; 254 int error; 255 xGLXSingleReply reply = { 0, }; 256 257 __GLX_DECLARE_SWAP_VARIABLES; 258 259 REQUEST_SIZE_MATCH(xGLXSingleReq); 260 261 __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); 262 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); 263 if (!cx) { 264 return error; 265 } 266 267 /* Do a local glFinish */ 268 glFinish(); 269 270 /* Send empty reply packet to indicate finish is finished */ 271 __GLX_BEGIN_REPLY(0); 272 __GLX_PUT_RETVAL(0); 273 __GLX_SWAP_REPLY_HEADER(); 274 __GLX_SEND_HEADER(); 275 276 return Success; 277} 278 279int 280__glXDispSwap_GetString(__GLXclientState * cl, GLbyte * pc) 281{ 282 return DoGetString(cl, pc, GL_TRUE); 283} 284