render2swap.c revision 35c4bbdf
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
40void
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
75void
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
119void
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
167void
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
223static void
224swapArray(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
283void
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