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 "unpack.h"
37 #include "indirect_size.h"
38 #include "indirect_dispatch.h"
39 
40 void
__glXDispSwap_Map1f(GLbyte * pc)41 __glXDispSwap_Map1f(GLbyte * pc)
42 {
43     GLint order, k;
44     GLfloat u1, u2, *points;
45     GLenum target;
46     GLint compsize;
47 
48     __GLX_DECLARE_SWAP_VARIABLES;
49     __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
50 
51     __GLX_SWAP_INT(pc + 0);
52     __GLX_SWAP_INT(pc + 12);
53     __GLX_SWAP_FLOAT(pc + 4);
54     __GLX_SWAP_FLOAT(pc + 8);
55 
56     target = *(GLenum *) (pc + 0);
57     order = *(GLint *) (pc + 12);
58     u1 = *(GLfloat *) (pc + 4);
59     u2 = *(GLfloat *) (pc + 8);
60     points = (GLfloat *) (pc + 16);
61     k = __glMap1f_size(target);
62 
63     if (order <= 0 || k < 0) {
64         /* Erroneous command. */
65         compsize = 0;
66     }
67     else {
68         compsize = order * k;
69     }
70     __GLX_SWAP_FLOAT_ARRAY(points, compsize);
71 
72     glMap1f(target, u1, u2, k, order, points);
73 }
74 
75 void
__glXDispSwap_Map2f(GLbyte * pc)76 __glXDispSwap_Map2f(GLbyte * pc)
77 {
78     GLint uorder, vorder, ustride, vstride, k;
79     GLfloat u1, u2, v1, v2, *points;
80     GLenum target;
81     GLint compsize;
82 
83     __GLX_DECLARE_SWAP_VARIABLES;
84     __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
85 
86     __GLX_SWAP_INT(pc + 0);
87     __GLX_SWAP_INT(pc + 12);
88     __GLX_SWAP_INT(pc + 24);
89     __GLX_SWAP_FLOAT(pc + 4);
90     __GLX_SWAP_FLOAT(pc + 8);
91     __GLX_SWAP_FLOAT(pc + 16);
92     __GLX_SWAP_FLOAT(pc + 20);
93 
94     target = *(GLenum *) (pc + 0);
95     uorder = *(GLint *) (pc + 12);
96     vorder = *(GLint *) (pc + 24);
97     u1 = *(GLfloat *) (pc + 4);
98     u2 = *(GLfloat *) (pc + 8);
99     v1 = *(GLfloat *) (pc + 16);
100     v2 = *(GLfloat *) (pc + 20);
101     points = (GLfloat *) (pc + 28);
102 
103     k = __glMap2f_size(target);
104     ustride = vorder * k;
105     vstride = k;
106 
107     if (vorder <= 0 || uorder <= 0 || k < 0) {
108         /* Erroneous command. */
109         compsize = 0;
110     }
111     else {
112         compsize = uorder * vorder * k;
113     }
114     __GLX_SWAP_FLOAT_ARRAY(points, compsize);
115 
116     glMap2f(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points);
117 }
118 
119 void
__glXDispSwap_Map1d(GLbyte * pc)120 __glXDispSwap_Map1d(GLbyte * pc)
121 {
122     GLint order, k, compsize;
123     GLenum target;
124     GLdouble u1, u2, *points;
125 
126     __GLX_DECLARE_SWAP_VARIABLES;
127     __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
128 
129     __GLX_SWAP_DOUBLE(pc + 0);
130     __GLX_SWAP_DOUBLE(pc + 8);
131     __GLX_SWAP_INT(pc + 16);
132     __GLX_SWAP_INT(pc + 20);
133 
134     target = *(GLenum *) (pc + 16);
135     order = *(GLint *) (pc + 20);
136     k = __glMap1d_size(target);
137     if (order <= 0 || k < 0) {
138         /* Erroneous command. */
139         compsize = 0;
140     }
141     else {
142         compsize = order * k;
143     }
144     __GLX_GET_DOUBLE(u1, pc);
145     __GLX_GET_DOUBLE(u2, pc + 8);
146     __GLX_SWAP_DOUBLE_ARRAY(pc + 24, compsize);
147     pc += 24;
148 
149 #ifdef __GLX_ALIGN64
150     if (((unsigned long) pc) & 7) {
151         /*
152          ** Copy the doubles up 4 bytes, trashing the command but aligning
153          ** the data in the process
154          */
155         __GLX_MEM_COPY(pc - 4, pc, compsize * 8);
156         points = (GLdouble *) (pc - 4);
157     }
158     else {
159         points = (GLdouble *) pc;
160     }
161 #else
162     points = (GLdouble *) pc;
163 #endif
164     glMap1d(target, u1, u2, k, order, points);
165 }
166 
167 void
__glXDispSwap_Map2d(GLbyte * pc)168 __glXDispSwap_Map2d(GLbyte * pc)
169 {
170     GLdouble u1, u2, v1, v2, *points;
171     GLint uorder, vorder, ustride, vstride, k, compsize;
172     GLenum target;
173 
174     __GLX_DECLARE_SWAP_VARIABLES;
175     __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
176 
177     __GLX_SWAP_DOUBLE(pc + 0);
178     __GLX_SWAP_DOUBLE(pc + 8);
179     __GLX_SWAP_DOUBLE(pc + 16);
180     __GLX_SWAP_DOUBLE(pc + 24);
181     __GLX_SWAP_INT(pc + 32);
182     __GLX_SWAP_INT(pc + 36);
183     __GLX_SWAP_INT(pc + 40);
184 
185     target = *(GLenum *) (pc + 32);
186     uorder = *(GLint *) (pc + 36);
187     vorder = *(GLint *) (pc + 40);
188     k = __glMap2d_size(target);
189     if (vorder <= 0 || uorder <= 0 || k < 0) {
190         /* Erroneous command. */
191         compsize = 0;
192     }
193     else {
194         compsize = uorder * vorder * k;
195     }
196     __GLX_GET_DOUBLE(u1, pc);
197     __GLX_GET_DOUBLE(u2, pc + 8);
198     __GLX_GET_DOUBLE(v1, pc + 16);
199     __GLX_GET_DOUBLE(v2, pc + 24);
200     __GLX_SWAP_DOUBLE_ARRAY(pc + 44, compsize);
201     pc += 44;
202     ustride = vorder * k;
203     vstride = k;
204 
205 #ifdef __GLX_ALIGN64
206     if (((unsigned long) pc) & 7) {
207         /*
208          ** Copy the doubles up 4 bytes, trashing the command but aligning
209          ** the data in the process
210          */
211         __GLX_MEM_COPY(pc - 4, pc, compsize * 8);
212         points = (GLdouble *) (pc - 4);
213     }
214     else {
215         points = (GLdouble *) pc;
216     }
217 #else
218     points = (GLdouble *) pc;
219 #endif
220     glMap2d(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points);
221 }
222 
223 static void
swapArray(GLint numVals,GLenum datatype,GLint stride,GLint numVertexes,GLbyte * pc)224 swapArray(GLint numVals, GLenum datatype,
225           GLint stride, GLint numVertexes, GLbyte * pc)
226 {
227     int i, j;
228 
229     __GLX_DECLARE_SWAP_VARIABLES;
230 
231     switch (datatype) {
232     case GL_BYTE:
233     case GL_UNSIGNED_BYTE:
234         /* don't need to swap */
235         return;
236     case GL_SHORT:
237     case GL_UNSIGNED_SHORT:
238         for (i = 0; i < numVertexes; i++) {
239             GLshort *pVal = (GLshort *) pc;
240 
241             for (j = 0; j < numVals; j++) {
242                 __GLX_SWAP_SHORT(&pVal[j]);
243             }
244             pc += stride;
245         }
246         break;
247     case GL_INT:
248     case GL_UNSIGNED_INT:
249         for (i = 0; i < numVertexes; i++) {
250             GLint *pVal = (GLint *) pc;
251 
252             for (j = 0; j < numVals; j++) {
253                 __GLX_SWAP_INT(&pVal[j]);
254             }
255             pc += stride;
256         }
257         break;
258     case GL_FLOAT:
259         for (i = 0; i < numVertexes; i++) {
260             GLfloat *pVal = (GLfloat *) pc;
261 
262             for (j = 0; j < numVals; j++) {
263                 __GLX_SWAP_FLOAT(&pVal[j]);
264             }
265             pc += stride;
266         }
267         break;
268     case GL_DOUBLE:
269         for (i = 0; i < numVertexes; i++) {
270             GLdouble *pVal = (GLdouble *) pc;
271 
272             for (j = 0; j < numVals; j++) {
273                 __GLX_SWAP_DOUBLE(&pVal[j]);
274             }
275             pc += stride;
276         }
277         break;
278     default:
279         return;
280     }
281 }
282 
283 void
__glXDispSwap_DrawArrays(GLbyte * pc)284 __glXDispSwap_DrawArrays(GLbyte * pc)
285 {
286     __GLXdispatchDrawArraysHeader *hdr = (__GLXdispatchDrawArraysHeader *) pc;
287     __GLXdispatchDrawArraysComponentHeader *compHeader;
288     GLint numVertexes = hdr->numVertexes;
289     GLint numComponents = hdr->numComponents;
290     GLenum primType = hdr->primType;
291     GLint stride = 0;
292     int i;
293 
294     __GLX_DECLARE_SWAP_VARIABLES;
295 
296     __GLX_SWAP_INT(&numVertexes);
297     __GLX_SWAP_INT(&numComponents);
298     __GLX_SWAP_INT(&primType);
299 
300     pc += sizeof(__GLXdispatchDrawArraysHeader);
301     compHeader = (__GLXdispatchDrawArraysComponentHeader *) pc;
302 
303     /* compute stride (same for all component arrays) */
304     for (i = 0; i < numComponents; i++) {
305         GLenum datatype = compHeader[i].datatype;
306         GLint numVals = compHeader[i].numVals;
307         GLenum component = compHeader[i].component;
308 
309         __GLX_SWAP_INT(&datatype);
310         __GLX_SWAP_INT(&numVals);
311         __GLX_SWAP_INT(&component);
312 
313         stride += __GLX_PAD(numVals * __glXTypeSize(datatype));
314     }
315 
316     pc += numComponents * sizeof(__GLXdispatchDrawArraysComponentHeader);
317 
318     /* set up component arrays */
319     for (i = 0; i < numComponents; i++) {
320         GLenum datatype = compHeader[i].datatype;
321         GLint numVals = compHeader[i].numVals;
322         GLenum component = compHeader[i].component;
323 
324         __GLX_SWAP_INT(&datatype);
325         __GLX_SWAP_INT(&numVals);
326         __GLX_SWAP_INT(&component);
327 
328         swapArray(numVals, datatype, stride, numVertexes, pc);
329 
330         switch (component) {
331         case GL_VERTEX_ARRAY:
332             glEnableClientState(GL_VERTEX_ARRAY);
333             glVertexPointer(numVals, datatype, stride, pc);
334             break;
335         case GL_NORMAL_ARRAY:
336             glEnableClientState(GL_NORMAL_ARRAY);
337             glNormalPointer(datatype, stride, pc);
338             break;
339         case GL_COLOR_ARRAY:
340             glEnableClientState(GL_COLOR_ARRAY);
341             glColorPointer(numVals, datatype, stride, pc);
342             break;
343         case GL_INDEX_ARRAY:
344             glEnableClientState(GL_INDEX_ARRAY);
345             glIndexPointer(datatype, stride, pc);
346             break;
347         case GL_TEXTURE_COORD_ARRAY:
348             glEnableClientState(GL_TEXTURE_COORD_ARRAY);
349             glTexCoordPointer(numVals, datatype, stride, pc);
350             break;
351         case GL_EDGE_FLAG_ARRAY:
352             glEnableClientState(GL_EDGE_FLAG_ARRAY);
353             glEdgeFlagPointer(stride, (const GLboolean *) pc);
354             break;
355         case GL_SECONDARY_COLOR_ARRAY:
356         {
357             PFNGLSECONDARYCOLORPOINTERPROC SecondaryColorPointerEXT =
358                 __glGetProcAddress("glSecondaryColorPointerEXT");
359             glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
360             SecondaryColorPointerEXT(numVals, datatype, stride, pc);
361             break;
362         }
363         case GL_FOG_COORD_ARRAY:
364         {
365             PFNGLFOGCOORDPOINTERPROC FogCoordPointerEXT =
366                 __glGetProcAddress("glFogCoordPointerEXT");
367             glEnableClientState(GL_FOG_COORD_ARRAY);
368             FogCoordPointerEXT(datatype, stride, pc);
369             break;
370         }
371         default:
372             break;
373         }
374 
375         pc += __GLX_PAD(numVals * __glXTypeSize(datatype));
376     }
377 
378     glDrawArrays(primType, 0, numVertexes);
379 
380     /* turn off anything we might have turned on */
381     glDisableClientState(GL_VERTEX_ARRAY);
382     glDisableClientState(GL_NORMAL_ARRAY);
383     glDisableClientState(GL_COLOR_ARRAY);
384     glDisableClientState(GL_INDEX_ARRAY);
385     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
386     glDisableClientState(GL_EDGE_FLAG_ARRAY);
387     glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
388     glDisableClientState(GL_FOG_COORD_ARRAY);
389 }
390