single2swap.c revision 0b0d8713
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#include "glapitable.h" 414642e01fSmrg#include "glapi.h" 424642e01fSmrg#include "glthread.h" 434642e01fSmrg#include "dispatch.h" 444642e01fSmrg 454642e01fSmrgint __glXDispSwap_FeedbackBuffer(__GLXclientState *cl, GLbyte *pc) 464642e01fSmrg{ 470b0d8713Smrg ClientPtr client = cl->client; 484642e01fSmrg GLsizei size; 494642e01fSmrg GLenum type; 504642e01fSmrg __GLX_DECLARE_SWAP_VARIABLES; 514642e01fSmrg __GLXcontext *cx; 524642e01fSmrg int error; 534642e01fSmrg 540b0d8713Smrg REQUEST_FIXED_SIZE(xGLXSingleReq, 8); 550b0d8713Smrg 564642e01fSmrg __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag); 574642e01fSmrg cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); 584642e01fSmrg if (!cx) { 594642e01fSmrg return error; 604642e01fSmrg } 614642e01fSmrg 624642e01fSmrg pc += __GLX_SINGLE_HDR_SIZE; 634642e01fSmrg __GLX_SWAP_INT(pc+0); 644642e01fSmrg __GLX_SWAP_INT(pc+4); 654642e01fSmrg size = *(GLsizei *)(pc+0); 664642e01fSmrg type = *(GLenum *)(pc+4); 674642e01fSmrg if (cx->feedbackBufSize < size) { 686747b715Smrg cx->feedbackBuf = (GLfloat *) realloc(cx->feedbackBuf, 694642e01fSmrg (size_t) size 704642e01fSmrg * __GLX_SIZE_FLOAT32); 714642e01fSmrg if (!cx->feedbackBuf) { 724642e01fSmrg cl->client->errorValue = size; 734642e01fSmrg return BadAlloc; 744642e01fSmrg } 754642e01fSmrg cx->feedbackBufSize = size; 764642e01fSmrg } 774642e01fSmrg CALL_FeedbackBuffer( GET_DISPATCH(), (size, type, cx->feedbackBuf) ); 784642e01fSmrg __GLX_NOTE_UNFLUSHED_CMDS(cx); 794642e01fSmrg return Success; 804642e01fSmrg} 814642e01fSmrg 824642e01fSmrgint __glXDispSwap_SelectBuffer(__GLXclientState *cl, GLbyte *pc) 834642e01fSmrg{ 840b0d8713Smrg ClientPtr client = cl->client; 854642e01fSmrg __GLXcontext *cx; 864642e01fSmrg GLsizei size; 874642e01fSmrg __GLX_DECLARE_SWAP_VARIABLES; 884642e01fSmrg int error; 894642e01fSmrg 900b0d8713Smrg REQUEST_FIXED_SIZE(xGLXSingleReq, 4); 910b0d8713Smrg 924642e01fSmrg __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag); 934642e01fSmrg cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); 944642e01fSmrg if (!cx) { 954642e01fSmrg return error; 964642e01fSmrg } 974642e01fSmrg 984642e01fSmrg pc += __GLX_SINGLE_HDR_SIZE; 994642e01fSmrg __GLX_SWAP_INT(pc+0); 1004642e01fSmrg size = *(GLsizei *)(pc+0); 1014642e01fSmrg if (cx->selectBufSize < size) { 1026747b715Smrg cx->selectBuf = (GLuint *) realloc(cx->selectBuf, 1034642e01fSmrg (size_t) size 1044642e01fSmrg * __GLX_SIZE_CARD32); 1054642e01fSmrg if (!cx->selectBuf) { 1064642e01fSmrg cl->client->errorValue = size; 1074642e01fSmrg return BadAlloc; 1084642e01fSmrg } 1094642e01fSmrg cx->selectBufSize = size; 1104642e01fSmrg } 1114642e01fSmrg CALL_SelectBuffer( GET_DISPATCH(), (size, cx->selectBuf) ); 1124642e01fSmrg __GLX_NOTE_UNFLUSHED_CMDS(cx); 1134642e01fSmrg return Success; 1144642e01fSmrg} 1154642e01fSmrg 1164642e01fSmrgint __glXDispSwap_RenderMode(__GLXclientState *cl, GLbyte *pc) 1174642e01fSmrg{ 1180b0d8713Smrg ClientPtr client = cl->client; 1194642e01fSmrg __GLXcontext *cx; 1204642e01fSmrg xGLXRenderModeReply reply; 1214642e01fSmrg GLint nitems=0, retBytes=0, retval, newModeCheck; 1224642e01fSmrg GLubyte *retBuffer = NULL; 1234642e01fSmrg GLenum newMode; 1244642e01fSmrg __GLX_DECLARE_SWAP_VARIABLES; 1254642e01fSmrg __GLX_DECLARE_SWAP_ARRAY_VARIABLES; 1264642e01fSmrg int error; 1274642e01fSmrg 1280b0d8713Smrg REQUEST_FIXED_SIZE(xGLXSingleReq, 4); 1290b0d8713Smrg 1304642e01fSmrg __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag); 1314642e01fSmrg cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); 1324642e01fSmrg if (!cx) { 1334642e01fSmrg return error; 1344642e01fSmrg } 1354642e01fSmrg 1364642e01fSmrg pc += __GLX_SINGLE_HDR_SIZE; 1374642e01fSmrg __GLX_SWAP_INT(pc); 1384642e01fSmrg newMode = *(GLenum*) pc; 1394642e01fSmrg retval = CALL_RenderMode( GET_DISPATCH(), (newMode) ); 1404642e01fSmrg 1414642e01fSmrg /* Check that render mode worked */ 1424642e01fSmrg CALL_GetIntegerv( GET_DISPATCH(), (GL_RENDER_MODE, &newModeCheck) ); 1434642e01fSmrg if (newModeCheck != newMode) { 1444642e01fSmrg /* Render mode change failed. Bail */ 1454642e01fSmrg newMode = newModeCheck; 1464642e01fSmrg goto noChangeAllowed; 1474642e01fSmrg } 1484642e01fSmrg 1494642e01fSmrg /* 1504642e01fSmrg ** Render mode might have still failed if we get here. But in this 1514642e01fSmrg ** case we can't really tell, nor does it matter. If it did fail, it 1524642e01fSmrg ** will return 0, and thus we won't send any data across the wire. 1534642e01fSmrg */ 1544642e01fSmrg 1554642e01fSmrg switch (cx->renderMode) { 1564642e01fSmrg case GL_RENDER: 1574642e01fSmrg cx->renderMode = newMode; 1584642e01fSmrg break; 1594642e01fSmrg case GL_FEEDBACK: 1604642e01fSmrg if (retval < 0) { 1614642e01fSmrg /* Overflow happened. Copy the entire buffer */ 1624642e01fSmrg nitems = cx->feedbackBufSize; 1634642e01fSmrg } else { 1644642e01fSmrg nitems = retval; 1654642e01fSmrg } 1664642e01fSmrg retBytes = nitems * __GLX_SIZE_FLOAT32; 1674642e01fSmrg retBuffer = (GLubyte*) cx->feedbackBuf; 1684642e01fSmrg __GLX_SWAP_FLOAT_ARRAY((GLbyte *)retBuffer, nitems); 1694642e01fSmrg cx->renderMode = newMode; 1704642e01fSmrg break; 1714642e01fSmrg case GL_SELECT: 1724642e01fSmrg if (retval < 0) { 1734642e01fSmrg /* Overflow happened. Copy the entire buffer */ 1744642e01fSmrg nitems = cx->selectBufSize; 1754642e01fSmrg } else { 1764642e01fSmrg GLuint *bp = cx->selectBuf; 1774642e01fSmrg GLint i; 1784642e01fSmrg 1794642e01fSmrg /* 1804642e01fSmrg ** Figure out how many bytes of data need to be sent. Parse 1814642e01fSmrg ** the selection buffer to determine this fact as the 1824642e01fSmrg ** return value is the number of hits, not the number of 1834642e01fSmrg ** items in the buffer. 1844642e01fSmrg */ 1854642e01fSmrg nitems = 0; 1864642e01fSmrg i = retval; 1874642e01fSmrg while (--i >= 0) { 1884642e01fSmrg GLuint n; 1894642e01fSmrg 1904642e01fSmrg /* Parse select data for this hit */ 1914642e01fSmrg n = *bp; 1924642e01fSmrg bp += 3 + n; 1934642e01fSmrg } 1944642e01fSmrg nitems = bp - cx->selectBuf; 1954642e01fSmrg } 1964642e01fSmrg retBytes = nitems * __GLX_SIZE_CARD32; 1974642e01fSmrg retBuffer = (GLubyte*) cx->selectBuf; 1984642e01fSmrg __GLX_SWAP_INT_ARRAY((GLbyte *)retBuffer, nitems); 1994642e01fSmrg cx->renderMode = newMode; 2004642e01fSmrg break; 2014642e01fSmrg } 2024642e01fSmrg 2034642e01fSmrg /* 2044642e01fSmrg ** First reply is the number of elements returned in the feedback or 2054642e01fSmrg ** selection array, as per the API for glRenderMode itself. 2064642e01fSmrg */ 2074642e01fSmrg noChangeAllowed:; 2084642e01fSmrg reply.length = nitems; 2094642e01fSmrg reply.type = X_Reply; 2104642e01fSmrg reply.sequenceNumber = client->sequence; 2114642e01fSmrg reply.retval = retval; 2124642e01fSmrg reply.size = nitems; 2134642e01fSmrg reply.newMode = newMode; 2144642e01fSmrg __GLX_SWAP_SHORT(&reply.sequenceNumber); 2154642e01fSmrg __GLX_SWAP_INT(&reply.length); 2164642e01fSmrg __GLX_SWAP_INT(&reply.retval); 2174642e01fSmrg __GLX_SWAP_INT(&reply.size); 2184642e01fSmrg __GLX_SWAP_INT(&reply.newMode); 2194642e01fSmrg WriteToClient(client, sz_xGLXRenderModeReply, (char *)&reply); 2204642e01fSmrg if (retBytes) { 2214642e01fSmrg WriteToClient(client, retBytes, (char *)retBuffer); 2224642e01fSmrg } 2234642e01fSmrg return Success; 2244642e01fSmrg} 2254642e01fSmrg 2264642e01fSmrgint __glXDispSwap_Flush(__GLXclientState *cl, GLbyte *pc) 2274642e01fSmrg{ 2280b0d8713Smrg ClientPtr client = cl->client; 2294642e01fSmrg __GLXcontext *cx; 2304642e01fSmrg int error; 2314642e01fSmrg __GLX_DECLARE_SWAP_VARIABLES; 2324642e01fSmrg 2330b0d8713Smrg REQUEST_SIZE_MATCH(xGLXSingleReq); 2340b0d8713Smrg 2354642e01fSmrg __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag); 2364642e01fSmrg cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); 2374642e01fSmrg if (!cx) { 2384642e01fSmrg return error; 2394642e01fSmrg } 2404642e01fSmrg 2414642e01fSmrg CALL_Flush( GET_DISPATCH(), () ); 2424642e01fSmrg __GLX_NOTE_FLUSHED_CMDS(cx); 2434642e01fSmrg return Success; 2444642e01fSmrg} 2454642e01fSmrg 2464642e01fSmrgint __glXDispSwap_Finish(__GLXclientState *cl, GLbyte *pc) 2474642e01fSmrg{ 2480b0d8713Smrg ClientPtr client = cl->client; 2494642e01fSmrg __GLXcontext *cx; 2504642e01fSmrg int error; 2514642e01fSmrg __GLX_DECLARE_SWAP_VARIABLES; 2524642e01fSmrg 2530b0d8713Smrg REQUEST_SIZE_MATCH(xGLXSingleReq); 2540b0d8713Smrg 2554642e01fSmrg __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag); 2564642e01fSmrg cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); 2574642e01fSmrg if (!cx) { 2584642e01fSmrg return error; 2594642e01fSmrg } 2604642e01fSmrg 2614642e01fSmrg /* Do a local glFinish */ 2624642e01fSmrg CALL_Finish( GET_DISPATCH(), () ); 2634642e01fSmrg __GLX_NOTE_FLUSHED_CMDS(cx); 2644642e01fSmrg 2654642e01fSmrg /* Send empty reply packet to indicate finish is finished */ 2664642e01fSmrg __GLX_BEGIN_REPLY(0); 2674642e01fSmrg __GLX_PUT_RETVAL(0); 2684642e01fSmrg __GLX_SWAP_REPLY_HEADER(); 2694642e01fSmrg __GLX_SEND_HEADER(); 2704642e01fSmrg 2714642e01fSmrg return Success; 2724642e01fSmrg} 2734642e01fSmrg 2744642e01fSmrgint __glXDispSwap_GetString(__GLXclientState *cl, GLbyte *pc) 2754642e01fSmrg{ 2764642e01fSmrg return DoGetString(cl, pc, GL_TRUE); 2774642e01fSmrg} 278