single2swap.c revision 7e31ba66
14642e01fSmrg/* 24642e01fSmrg * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) 34642e01fSmrg * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. 44642e01fSmrg * 54642e01fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 64642e01fSmrg * copy of this software and associated documentation files (the "Software"), 74642e01fSmrg * to deal in the Software without restriction, including without limitation 84642e01fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 94642e01fSmrg * and/or sell copies of the Software, and to permit persons to whom the 104642e01fSmrg * Software is furnished to do so, subject to the following conditions: 114642e01fSmrg * 124642e01fSmrg * The above copyright notice including the dates of first publication and 134642e01fSmrg * either this permission notice or a reference to 144642e01fSmrg * http://oss.sgi.com/projects/FreeB/ 154642e01fSmrg * shall be included in all copies or substantial portions of the Software. 164642e01fSmrg * 174642e01fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 184642e01fSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 194642e01fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 204642e01fSmrg * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 214642e01fSmrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 224642e01fSmrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 234642e01fSmrg * SOFTWARE. 244642e01fSmrg * 254642e01fSmrg * Except as contained in this notice, the name of Silicon Graphics, Inc. 264642e01fSmrg * shall not be used in advertising or otherwise to promote the sale, use or 274642e01fSmrg * other dealings in this Software without prior written authorization from 284642e01fSmrg * Silicon Graphics, Inc. 294642e01fSmrg */ 304642e01fSmrg 314642e01fSmrg#ifdef HAVE_DIX_CONFIG_H 324642e01fSmrg#include <dix-config.h> 334642e01fSmrg#endif 344642e01fSmrg 354642e01fSmrg#include "glxserver.h" 364642e01fSmrg#include "glxutil.h" 374642e01fSmrg#include "glxext.h" 384642e01fSmrg#include "indirect_dispatch.h" 394642e01fSmrg#include "unpack.h" 404642e01fSmrg 41f7df2e56Smrgint 42f7df2e56Smrg__glXDispSwap_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc) 434642e01fSmrg{ 440b0d8713Smrg ClientPtr client = cl->client; 454642e01fSmrg GLsizei size; 464642e01fSmrg GLenum type; 47f7df2e56Smrg 484642e01fSmrg __GLX_DECLARE_SWAP_VARIABLES; 494642e01fSmrg __GLXcontext *cx; 504642e01fSmrg int error; 514642e01fSmrg 520b0d8713Smrg REQUEST_FIXED_SIZE(xGLXSingleReq, 8); 530b0d8713Smrg 54f7df2e56Smrg __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); 554642e01fSmrg cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); 564642e01fSmrg if (!cx) { 57f7df2e56Smrg return error; 584642e01fSmrg } 594642e01fSmrg 604642e01fSmrg pc += __GLX_SINGLE_HDR_SIZE; 61f7df2e56Smrg __GLX_SWAP_INT(pc + 0); 62f7df2e56Smrg __GLX_SWAP_INT(pc + 4); 63f7df2e56Smrg size = *(GLsizei *) (pc + 0); 64f7df2e56Smrg type = *(GLenum *) (pc + 4); 654642e01fSmrg if (cx->feedbackBufSize < size) { 66f7df2e56Smrg cx->feedbackBuf = reallocarray(cx->feedbackBuf, 67f7df2e56Smrg (size_t) size, __GLX_SIZE_FLOAT32); 68f7df2e56Smrg if (!cx->feedbackBuf) { 69f7df2e56Smrg cl->client->errorValue = size; 70f7df2e56Smrg return BadAlloc; 71f7df2e56Smrg } 72f7df2e56Smrg cx->feedbackBufSize = size; 734642e01fSmrg } 74f7df2e56Smrg glFeedbackBuffer(size, type, cx->feedbackBuf); 754642e01fSmrg return Success; 764642e01fSmrg} 774642e01fSmrg 78f7df2e56Smrgint 79f7df2e56Smrg__glXDispSwap_SelectBuffer(__GLXclientState * cl, GLbyte * pc) 804642e01fSmrg{ 810b0d8713Smrg ClientPtr client = cl->client; 824642e01fSmrg __GLXcontext *cx; 834642e01fSmrg GLsizei size; 84f7df2e56Smrg 854642e01fSmrg __GLX_DECLARE_SWAP_VARIABLES; 864642e01fSmrg int error; 874642e01fSmrg 880b0d8713Smrg REQUEST_FIXED_SIZE(xGLXSingleReq, 4); 890b0d8713Smrg 90f7df2e56Smrg __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); 914642e01fSmrg cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); 924642e01fSmrg if (!cx) { 93f7df2e56Smrg return error; 944642e01fSmrg } 954642e01fSmrg 964642e01fSmrg pc += __GLX_SINGLE_HDR_SIZE; 97f7df2e56Smrg __GLX_SWAP_INT(pc + 0); 98f7df2e56Smrg size = *(GLsizei *) (pc + 0); 994642e01fSmrg if (cx->selectBufSize < size) { 100f7df2e56Smrg cx->selectBuf = reallocarray(cx->selectBuf, 101f7df2e56Smrg (size_t) size, __GLX_SIZE_CARD32); 102f7df2e56Smrg if (!cx->selectBuf) { 103f7df2e56Smrg cl->client->errorValue = size; 104f7df2e56Smrg return BadAlloc; 105f7df2e56Smrg } 106f7df2e56Smrg cx->selectBufSize = size; 1074642e01fSmrg } 108f7df2e56Smrg glSelectBuffer(size, cx->selectBuf); 1094642e01fSmrg return Success; 1104642e01fSmrg} 1114642e01fSmrg 112f7df2e56Smrgint 113f7df2e56Smrg__glXDispSwap_RenderMode(__GLXclientState * cl, GLbyte * pc) 1144642e01fSmrg{ 1150b0d8713Smrg ClientPtr client = cl->client; 1164642e01fSmrg __GLXcontext *cx; 1174642e01fSmrg xGLXRenderModeReply reply; 118f7df2e56Smrg GLint nitems = 0, retBytes = 0, retval, newModeCheck; 1194642e01fSmrg GLubyte *retBuffer = NULL; 1204642e01fSmrg GLenum newMode; 121f7df2e56Smrg 1224642e01fSmrg __GLX_DECLARE_SWAP_VARIABLES; 1234642e01fSmrg __GLX_DECLARE_SWAP_ARRAY_VARIABLES; 1244642e01fSmrg int error; 1254642e01fSmrg 1260b0d8713Smrg REQUEST_FIXED_SIZE(xGLXSingleReq, 4); 1270b0d8713Smrg 128f7df2e56Smrg __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); 1294642e01fSmrg cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); 1304642e01fSmrg if (!cx) { 131f7df2e56Smrg return error; 1324642e01fSmrg } 1334642e01fSmrg 1344642e01fSmrg pc += __GLX_SINGLE_HDR_SIZE; 1354642e01fSmrg __GLX_SWAP_INT(pc); 136f7df2e56Smrg newMode = *(GLenum *) pc; 137f7df2e56Smrg retval = glRenderMode(newMode); 1384642e01fSmrg 1394642e01fSmrg /* Check that render mode worked */ 140f7df2e56Smrg glGetIntegerv(GL_RENDER_MODE, &newModeCheck); 1414642e01fSmrg if (newModeCheck != newMode) { 142f7df2e56Smrg /* Render mode change failed. Bail */ 143f7df2e56Smrg newMode = newModeCheck; 144f7df2e56Smrg goto noChangeAllowed; 1454642e01fSmrg } 1464642e01fSmrg 1474642e01fSmrg /* 148f7df2e56Smrg ** Render mode might have still failed if we get here. But in this 149f7df2e56Smrg ** case we can't really tell, nor does it matter. If it did fail, it 150f7df2e56Smrg ** will return 0, and thus we won't send any data across the wire. 151f7df2e56Smrg */ 1524642e01fSmrg 1534642e01fSmrg switch (cx->renderMode) { 154f7df2e56Smrg case GL_RENDER: 155f7df2e56Smrg cx->renderMode = newMode; 156f7df2e56Smrg break; 157f7df2e56Smrg case GL_FEEDBACK: 158f7df2e56Smrg if (retval < 0) { 159f7df2e56Smrg /* Overflow happened. Copy the entire buffer */ 160f7df2e56Smrg nitems = cx->feedbackBufSize; 161f7df2e56Smrg } 162f7df2e56Smrg else { 163f7df2e56Smrg nitems = retval; 164f7df2e56Smrg } 165f7df2e56Smrg retBytes = nitems * __GLX_SIZE_FLOAT32; 166f7df2e56Smrg retBuffer = (GLubyte *) cx->feedbackBuf; 167f7df2e56Smrg __GLX_SWAP_FLOAT_ARRAY((GLbyte *) retBuffer, nitems); 168f7df2e56Smrg cx->renderMode = newMode; 169f7df2e56Smrg break; 170f7df2e56Smrg case GL_SELECT: 171f7df2e56Smrg if (retval < 0) { 172f7df2e56Smrg /* Overflow happened. Copy the entire buffer */ 173f7df2e56Smrg nitems = cx->selectBufSize; 174f7df2e56Smrg } 175f7df2e56Smrg else { 176f7df2e56Smrg GLuint *bp = cx->selectBuf; 177f7df2e56Smrg GLint i; 178f7df2e56Smrg 179f7df2e56Smrg /* 180f7df2e56Smrg ** Figure out how many bytes of data need to be sent. Parse 181f7df2e56Smrg ** the selection buffer to determine this fact as the 182f7df2e56Smrg ** return value is the number of hits, not the number of 183f7df2e56Smrg ** items in the buffer. 184f7df2e56Smrg */ 185f7df2e56Smrg nitems = 0; 186f7df2e56Smrg i = retval; 187f7df2e56Smrg while (--i >= 0) { 188f7df2e56Smrg GLuint n; 189f7df2e56Smrg 190f7df2e56Smrg /* Parse select data for this hit */ 191f7df2e56Smrg n = *bp; 192f7df2e56Smrg bp += 3 + n; 193f7df2e56Smrg } 194f7df2e56Smrg nitems = bp - cx->selectBuf; 195f7df2e56Smrg } 196f7df2e56Smrg retBytes = nitems * __GLX_SIZE_CARD32; 197f7df2e56Smrg retBuffer = (GLubyte *) cx->selectBuf; 198f7df2e56Smrg __GLX_SWAP_INT_ARRAY((GLbyte *) retBuffer, nitems); 199f7df2e56Smrg cx->renderMode = newMode; 200f7df2e56Smrg break; 2014642e01fSmrg } 2024642e01fSmrg 2034642e01fSmrg /* 204f7df2e56Smrg ** First reply is the number of elements returned in the feedback or 205f7df2e56Smrg ** selection array, as per the API for glRenderMode itself. 206f7df2e56Smrg */ 207f7df2e56Smrg noChangeAllowed:; 208f7df2e56Smrg reply = (xGLXRenderModeReply) { 209f7df2e56Smrg .type = X_Reply, 210f7df2e56Smrg .sequenceNumber = client->sequence, 211f7df2e56Smrg .length = nitems, 212f7df2e56Smrg .retval = retval, 213f7df2e56Smrg .size = nitems, 214f7df2e56Smrg .newMode = newMode 215f7df2e56Smrg }; 2164642e01fSmrg __GLX_SWAP_SHORT(&reply.sequenceNumber); 2174642e01fSmrg __GLX_SWAP_INT(&reply.length); 2184642e01fSmrg __GLX_SWAP_INT(&reply.retval); 2194642e01fSmrg __GLX_SWAP_INT(&reply.size); 2204642e01fSmrg __GLX_SWAP_INT(&reply.newMode); 221f7df2e56Smrg WriteToClient(client, sz_xGLXRenderModeReply, &reply); 2224642e01fSmrg if (retBytes) { 223f7df2e56Smrg WriteToClient(client, retBytes, retBuffer); 2244642e01fSmrg } 2254642e01fSmrg return Success; 2264642e01fSmrg} 2274642e01fSmrg 228f7df2e56Smrgint 229f7df2e56Smrg__glXDispSwap_Flush(__GLXclientState * cl, GLbyte * pc) 2304642e01fSmrg{ 231f7df2e56Smrg ClientPtr client = cl->client; 232f7df2e56Smrg __GLXcontext *cx; 233f7df2e56Smrg int error; 234f7df2e56Smrg 235f7df2e56Smrg __GLX_DECLARE_SWAP_VARIABLES; 236f7df2e56Smrg 237f7df2e56Smrg REQUEST_SIZE_MATCH(xGLXSingleReq); 238f7df2e56Smrg 239f7df2e56Smrg __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); 240f7df2e56Smrg cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); 241f7df2e56Smrg if (!cx) { 242f7df2e56Smrg return error; 243f7df2e56Smrg } 244f7df2e56Smrg 245f7df2e56Smrg glFlush(); 246f7df2e56Smrg return Success; 2474642e01fSmrg} 2484642e01fSmrg 249f7df2e56Smrgint 250f7df2e56Smrg__glXDispSwap_Finish(__GLXclientState * cl, GLbyte * pc) 2514642e01fSmrg{ 2520b0d8713Smrg ClientPtr client = cl->client; 2534642e01fSmrg __GLXcontext *cx; 2544642e01fSmrg int error; 2557e31ba66Smrg xGLXSingleReply reply = { 0, }; 256f7df2e56Smrg 2574642e01fSmrg __GLX_DECLARE_SWAP_VARIABLES; 2584642e01fSmrg 2590b0d8713Smrg REQUEST_SIZE_MATCH(xGLXSingleReq); 2600b0d8713Smrg 261f7df2e56Smrg __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); 2624642e01fSmrg cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); 2634642e01fSmrg if (!cx) { 264f7df2e56Smrg return error; 2654642e01fSmrg } 2664642e01fSmrg 2674642e01fSmrg /* Do a local glFinish */ 268f7df2e56Smrg glFinish(); 2694642e01fSmrg 2704642e01fSmrg /* Send empty reply packet to indicate finish is finished */ 2714642e01fSmrg __GLX_BEGIN_REPLY(0); 2724642e01fSmrg __GLX_PUT_RETVAL(0); 2734642e01fSmrg __GLX_SWAP_REPLY_HEADER(); 2744642e01fSmrg __GLX_SEND_HEADER(); 2754642e01fSmrg 2764642e01fSmrg return Success; 2774642e01fSmrg} 2784642e01fSmrg 279f7df2e56Smrgint 280f7df2e56Smrg__glXDispSwap_GetString(__GLXclientState * cl, GLbyte * pc) 2814642e01fSmrg{ 2824642e01fSmrg return DoGetString(cl, pc, GL_TRUE); 2834642e01fSmrg} 284