xref: /third_party/mesa3d/src/glx/render2.c (revision bf215546)
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#ifndef GLX_USE_APPLEGL
32
33#include "packrender.h"
34#include "indirect.h"
35#include "indirect_size.h"
36
37/*
38** This file contains routines that might need to be transported as
39** GLXRender or GLXRenderLarge commands, and these commands don't
40** use the pixel header.  See renderpix.c for those routines.
41*/
42
43void
44__indirect_glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride,
45                   GLint order, const GLdouble * pnts)
46{
47   __GLX_DECLARE_VARIABLES();
48   GLint k;
49
50   __GLX_LOAD_VARIABLES();
51   k = __glMap1d_size(target);
52   if (k == 0) {
53      __glXSetError(gc, GL_INVALID_ENUM);
54      return;
55   }
56   else if (stride < k || order <= 0) {
57      __glXSetError(gc, GL_INVALID_VALUE);
58      return;
59   }
60   compsize = k * order * __GLX_SIZE_FLOAT64;
61   cmdlen = 28 + compsize;
62   if (!gc->currentDpy)
63      return;
64
65   if (cmdlen <= gc->maxSmallRenderCommandSize) {
66      /* Use GLXRender protocol to send small command */
67      __GLX_BEGIN_VARIABLE(X_GLrop_Map1d, cmdlen);
68      __GLX_PUT_DOUBLE(4, u1);
69      __GLX_PUT_DOUBLE(12, u2);
70      __GLX_PUT_LONG(20, target);
71      __GLX_PUT_LONG(24, order);
72      /*
73       ** NOTE: the doubles that follow are not aligned because of 3
74       ** longs preceeding
75       */
76      __glFillMap1d(k, order, stride, pnts, (pc + 28));
77      __GLX_END(cmdlen);
78   }
79   else {
80      /* Use GLXRenderLarge protocol to send command */
81      __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map1d, cmdlen + 4);
82      __GLX_PUT_DOUBLE(8, u1);
83      __GLX_PUT_DOUBLE(16, u2);
84      __GLX_PUT_LONG(24, target);
85      __GLX_PUT_LONG(28, order);
86
87      /*
88       ** NOTE: the doubles that follow are not aligned because of 3
89       ** longs preceeding
90       */
91      if (stride != k) {
92         GLubyte *buf;
93
94         buf = malloc(compsize);
95         if (!buf) {
96            __glXSetError(gc, GL_OUT_OF_MEMORY);
97            return;
98         }
99         __glFillMap1d(k, order, stride, pnts, buf);
100         __glXSendLargeCommand(gc, pc, 32, buf, compsize);
101         free((char *) buf);
102      }
103      else {
104         /* Data is already packed.  Just send it out */
105         __glXSendLargeCommand(gc, pc, 32, pnts, compsize);
106      }
107   }
108}
109
110void
111__indirect_glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride,
112                   GLint order, const GLfloat * pnts)
113{
114   __GLX_DECLARE_VARIABLES();
115   GLint k;
116
117   __GLX_LOAD_VARIABLES();
118   k = __glMap1f_size(target);
119   if (k == 0) {
120      __glXSetError(gc, GL_INVALID_ENUM);
121      return;
122   }
123   else if (stride < k || order <= 0) {
124      __glXSetError(gc, GL_INVALID_VALUE);
125      return;
126   }
127   compsize = k * order * __GLX_SIZE_FLOAT32;
128   cmdlen = 20 + compsize;
129   if (!gc->currentDpy)
130      return;
131
132   /*
133    ** The order that arguments are packed is different from the order
134    ** for glMap1d.
135    */
136   if (cmdlen <= gc->maxSmallRenderCommandSize) {
137      /* Use GLXRender protocol to send small command */
138      __GLX_BEGIN_VARIABLE(X_GLrop_Map1f, cmdlen);
139      __GLX_PUT_LONG(4, target);
140      __GLX_PUT_FLOAT(8, u1);
141      __GLX_PUT_FLOAT(12, u2);
142      __GLX_PUT_LONG(16, order);
143      __glFillMap1f(k, order, stride, pnts, (GLubyte *) (pc + 20));
144      __GLX_END(cmdlen);
145   }
146   else {
147      /* Use GLXRenderLarge protocol to send command */
148      __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map1f, cmdlen + 4);
149      __GLX_PUT_LONG(8, target);
150      __GLX_PUT_FLOAT(12, u1);
151      __GLX_PUT_FLOAT(16, u2);
152      __GLX_PUT_LONG(20, order);
153
154      if (stride != k) {
155         GLubyte *buf;
156
157         buf = malloc(compsize);
158         if (!buf) {
159            __glXSetError(gc, GL_OUT_OF_MEMORY);
160            return;
161         }
162         __glFillMap1f(k, order, stride, pnts, buf);
163         __glXSendLargeCommand(gc, pc, 24, buf, compsize);
164         free((char *) buf);
165      }
166      else {
167         /* Data is already packed.  Just send it out */
168         __glXSendLargeCommand(gc, pc, 24, pnts, compsize);
169      }
170   }
171}
172
173void
174__indirect_glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustr,
175                   GLint uord, GLdouble v1, GLdouble v2, GLint vstr,
176                   GLint vord, const GLdouble * pnts)
177{
178   __GLX_DECLARE_VARIABLES();
179   GLint k;
180
181   __GLX_LOAD_VARIABLES();
182   k = __glMap2d_size(target);
183   if (k == 0) {
184      __glXSetError(gc, GL_INVALID_ENUM);
185      return;
186   }
187   else if (vstr < k || ustr < k || vord <= 0 || uord <= 0) {
188      __glXSetError(gc, GL_INVALID_VALUE);
189      return;
190   }
191   compsize = k * uord * vord * __GLX_SIZE_FLOAT64;
192   cmdlen = 48 + compsize;
193   if (!gc->currentDpy)
194      return;
195
196   if (cmdlen <= gc->maxSmallRenderCommandSize) {
197      /* Use GLXRender protocol to send small command */
198      __GLX_BEGIN_VARIABLE(X_GLrop_Map2d, cmdlen);
199      __GLX_PUT_DOUBLE(4, u1);
200      __GLX_PUT_DOUBLE(12, u2);
201      __GLX_PUT_DOUBLE(20, v1);
202      __GLX_PUT_DOUBLE(28, v2);
203      __GLX_PUT_LONG(36, target);
204      __GLX_PUT_LONG(40, uord);
205      __GLX_PUT_LONG(44, vord);
206      /*
207       ** Pack into a u-major ordering.
208       ** NOTE: the doubles that follow are not aligned because of 5
209       ** longs preceeding
210       */
211      __glFillMap2d(k, uord, vord, ustr, vstr, pnts, (GLdouble *) (pc + 48));
212      __GLX_END(cmdlen);
213   }
214   else {
215      /* Use GLXRenderLarge protocol to send command */
216      __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map2d, cmdlen + 4);
217      __GLX_PUT_DOUBLE(8, u1);
218      __GLX_PUT_DOUBLE(16, u2);
219      __GLX_PUT_DOUBLE(24, v1);
220      __GLX_PUT_DOUBLE(32, v2);
221      __GLX_PUT_LONG(40, target);
222      __GLX_PUT_LONG(44, uord);
223      __GLX_PUT_LONG(48, vord);
224
225      /*
226       ** NOTE: the doubles that follow are not aligned because of 5
227       ** longs preceeding
228       */
229      if ((vstr != k) || (ustr != k * vord)) {
230         GLdouble *buf;
231
232         buf = malloc(compsize);
233         if (!buf) {
234            __glXSetError(gc, GL_OUT_OF_MEMORY);
235            return;
236         }
237         /*
238          ** Pack into a u-major ordering.
239          */
240         __glFillMap2d(k, uord, vord, ustr, vstr, pnts, buf);
241         __glXSendLargeCommand(gc, pc, 52, buf, compsize);
242         free((char *) buf);
243      }
244      else {
245         /* Data is already packed.  Just send it out */
246         __glXSendLargeCommand(gc, pc, 52, pnts, compsize);
247      }
248   }
249}
250
251void
252__indirect_glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustr,
253                   GLint uord, GLfloat v1, GLfloat v2, GLint vstr, GLint vord,
254                   const GLfloat * pnts)
255{
256   __GLX_DECLARE_VARIABLES();
257   GLint k;
258
259   __GLX_LOAD_VARIABLES();
260   k = __glMap2f_size(target);
261   if (k == 0) {
262      __glXSetError(gc, GL_INVALID_ENUM);
263      return;
264   }
265   else if (vstr < k || ustr < k || vord <= 0 || uord <= 0) {
266      __glXSetError(gc, GL_INVALID_VALUE);
267      return;
268   }
269   compsize = k * uord * vord * __GLX_SIZE_FLOAT32;
270   cmdlen = 32 + compsize;
271   if (!gc->currentDpy)
272      return;
273
274   /*
275    ** The order that arguments are packed is different from the order
276    ** for glMap2d.
277    */
278   if (cmdlen <= gc->maxSmallRenderCommandSize) {
279      /* Use GLXRender protocol to send small command */
280      __GLX_BEGIN_VARIABLE(X_GLrop_Map2f, cmdlen);
281      __GLX_PUT_LONG(4, target);
282      __GLX_PUT_FLOAT(8, u1);
283      __GLX_PUT_FLOAT(12, u2);
284      __GLX_PUT_LONG(16, uord);
285      __GLX_PUT_FLOAT(20, v1);
286      __GLX_PUT_FLOAT(24, v2);
287      __GLX_PUT_LONG(28, vord);
288      /*
289       ** Pack into a u-major ordering.
290       */
291      __glFillMap2f(k, uord, vord, ustr, vstr, pnts, (GLfloat *) (pc + 32));
292      __GLX_END(cmdlen);
293   }
294   else {
295      /* Use GLXRenderLarge protocol to send command */
296      __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map2f, cmdlen + 4);
297      __GLX_PUT_LONG(8, target);
298      __GLX_PUT_FLOAT(12, u1);
299      __GLX_PUT_FLOAT(16, u2);
300      __GLX_PUT_LONG(20, uord);
301      __GLX_PUT_FLOAT(24, v1);
302      __GLX_PUT_FLOAT(28, v2);
303      __GLX_PUT_LONG(32, vord);
304
305      if ((vstr != k) || (ustr != k * vord)) {
306         GLfloat *buf;
307
308         buf = malloc(compsize);
309         if (!buf) {
310            __glXSetError(gc, GL_OUT_OF_MEMORY);
311            return;
312         }
313         /*
314          ** Pack into a u-major ordering.
315          */
316         __glFillMap2f(k, uord, vord, ustr, vstr, pnts, buf);
317         __glXSendLargeCommand(gc, pc, 36, buf, compsize);
318         free((char *) buf);
319      }
320      else {
321         /* Data is already packed.  Just send it out */
322         __glXSendLargeCommand(gc, pc, 36, pnts, compsize);
323      }
324   }
325}
326
327void
328__indirect_glEnable(GLenum cap)
329{
330   __GLX_DECLARE_VARIABLES();
331
332   __GLX_LOAD_VARIABLES();
333   if (!gc->currentDpy)
334      return;
335
336   switch (cap) {
337   case GL_COLOR_ARRAY:
338   case GL_EDGE_FLAG_ARRAY:
339   case GL_INDEX_ARRAY:
340   case GL_NORMAL_ARRAY:
341   case GL_TEXTURE_COORD_ARRAY:
342   case GL_VERTEX_ARRAY:
343   case GL_SECONDARY_COLOR_ARRAY:
344   case GL_FOG_COORD_ARRAY:
345      __indirect_glEnableClientState(cap);
346      return;
347   default:
348      break;
349   }
350
351   __GLX_BEGIN(X_GLrop_Enable, 8);
352   __GLX_PUT_LONG(4, cap);
353   __GLX_END(8);
354}
355
356void
357__indirect_glDisable(GLenum cap)
358{
359   __GLX_DECLARE_VARIABLES();
360
361   __GLX_LOAD_VARIABLES();
362   if (!gc->currentDpy)
363      return;
364
365   switch (cap) {
366   case GL_COLOR_ARRAY:
367   case GL_EDGE_FLAG_ARRAY:
368   case GL_INDEX_ARRAY:
369   case GL_NORMAL_ARRAY:
370   case GL_TEXTURE_COORD_ARRAY:
371   case GL_VERTEX_ARRAY:
372   case GL_SECONDARY_COLOR_ARRAY:
373   case GL_FOG_COORD_ARRAY:
374      __indirect_glDisableClientState(cap);
375      return;
376   default:
377      break;
378   }
379
380   __GLX_BEGIN(X_GLrop_Disable, 8);
381   __GLX_PUT_LONG(4, cap);
382   __GLX_END(8);
383}
384
385#endif
386