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