xref: /aosp_15_r20/external/mesa3d/src/glx/pixelstore.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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  * SPDX-License-Identifier: SGI-B-2.0
6  */
7 
8 #include "glxclient.h"
9 #include "indirect.h"
10 #include "util/rounding.h"
11 
12 #if !defined(__GNUC__)
13 #  define __builtin_expect(x, y) x
14 #endif
15 
16 /**
17  * Send glPixelStore command to the server
18  *
19  * \param gc     Current GLX context
20  * \param sop    Either \c X_GLsop_PixelStoref or \c X_GLsop_PixelStorei
21  * \param pname  Selector of which pixel parameter is to be set.
22  * \param param  Value that \c pname is set to.
23  *
24  * \sa __indirect_glPixelStorei,  __indirect_glPixelStoref
25  */
26 static void
send_PixelStore(struct glx_context * gc,unsigned sop,GLenum pname,const void * param)27 send_PixelStore(struct glx_context * gc, unsigned sop, GLenum pname,
28                 const void *param)
29 {
30    Display *const dpy = gc->currentDpy;
31    const GLuint cmdlen = 8;
32    if (__builtin_expect(dpy != NULL, 1)) {
33       GLubyte const *pc = __glXSetupSingleRequest(gc, sop, cmdlen);
34       (void) memcpy((void *) (pc + 0), (void *) (&pname), 4);
35       (void) memcpy((void *) (pc + 4), param, 4);
36       UnlockDisplay(dpy);
37       SyncHandle();
38    }
39    return;
40 }
41 
42 /*
43 ** Specify parameters that control the storage format of pixel arrays.
44 */
45 void
__indirect_glPixelStoref(GLenum pname,GLfloat param)46 __indirect_glPixelStoref(GLenum pname, GLfloat param)
47 {
48    struct glx_context *gc = __glXGetCurrentContext();
49    __GLXattribute *state = gc->client_state_private;
50    Display *dpy = gc->currentDpy;
51    GLuint a;
52 
53    if (!dpy)
54       return;
55 
56    switch (pname) {
57    case GL_PACK_ROW_LENGTH:
58       a = _mesa_lroundevenf(param);
59       if (((GLint) a) < 0) {
60          __glXSetError(gc, GL_INVALID_VALUE);
61          return;
62       }
63       state->storePack.rowLength = a;
64       break;
65    case GL_PACK_IMAGE_HEIGHT:
66       a = _mesa_lroundevenf(param);
67       if (((GLint) a) < 0) {
68          __glXSetError(gc, GL_INVALID_VALUE);
69          return;
70       }
71       state->storePack.imageHeight = a;
72       break;
73    case GL_PACK_SKIP_ROWS:
74       a = _mesa_lroundevenf(param);
75       if (((GLint) a) < 0) {
76          __glXSetError(gc, GL_INVALID_VALUE);
77          return;
78       }
79       state->storePack.skipRows = a;
80       break;
81    case GL_PACK_SKIP_PIXELS:
82       a = _mesa_lroundevenf(param);
83       if (((GLint) a) < 0) {
84          __glXSetError(gc, GL_INVALID_VALUE);
85          return;
86       }
87       state->storePack.skipPixels = a;
88       break;
89    case GL_PACK_SKIP_IMAGES:
90       a = _mesa_lroundevenf(param);
91       if (((GLint) a) < 0) {
92          __glXSetError(gc, GL_INVALID_VALUE);
93          return;
94       }
95       state->storePack.skipImages = a;
96       break;
97    case GL_PACK_ALIGNMENT:
98       a = _mesa_lroundevenf(param);
99       switch (a) {
100       case 1:
101       case 2:
102       case 4:
103       case 8:
104          state->storePack.alignment = a;
105          break;
106       default:
107          __glXSetError(gc, GL_INVALID_VALUE);
108          return;
109       }
110       break;
111    case GL_PACK_SWAP_BYTES:
112       state->storePack.swapEndian = (param != 0);
113       break;
114    case GL_PACK_LSB_FIRST:
115       state->storePack.lsbFirst = (param != 0);
116       break;
117 
118    case GL_UNPACK_ROW_LENGTH:
119       a = _mesa_lroundevenf(param);
120       if (((GLint) a) < 0) {
121          __glXSetError(gc, GL_INVALID_VALUE);
122          return;
123       }
124       state->storeUnpack.rowLength = a;
125       break;
126    case GL_UNPACK_IMAGE_HEIGHT:
127       a = _mesa_lroundevenf(param);
128       if (((GLint) a) < 0) {
129          __glXSetError(gc, GL_INVALID_VALUE);
130          return;
131       }
132       state->storeUnpack.imageHeight = a;
133       break;
134    case GL_UNPACK_SKIP_ROWS:
135       a = _mesa_lroundevenf(param);
136       if (((GLint) a) < 0) {
137          __glXSetError(gc, GL_INVALID_VALUE);
138          return;
139       }
140       state->storeUnpack.skipRows = a;
141       break;
142    case GL_UNPACK_SKIP_PIXELS:
143       a = _mesa_lroundevenf(param);
144       if (((GLint) a) < 0) {
145          __glXSetError(gc, GL_INVALID_VALUE);
146          return;
147       }
148       state->storeUnpack.skipPixels = a;
149       break;
150    case GL_UNPACK_SKIP_IMAGES:
151       a = _mesa_lroundevenf(param);
152       if (((GLint) a) < 0) {
153          __glXSetError(gc, GL_INVALID_VALUE);
154          return;
155       }
156       state->storeUnpack.skipImages = a;
157       break;
158    case GL_UNPACK_ALIGNMENT:
159       a = _mesa_lroundevenf(param);
160       switch (a) {
161       case 1:
162       case 2:
163       case 4:
164       case 8:
165          state->storeUnpack.alignment = a;
166          break;
167       default:
168          __glXSetError(gc, GL_INVALID_VALUE);
169          return;
170       }
171       break;
172    case GL_UNPACK_SWAP_BYTES:
173       state->storeUnpack.swapEndian = (param != 0);
174       break;
175    case GL_UNPACK_LSB_FIRST:
176       state->storeUnpack.lsbFirst = (param != 0);
177       break;
178 
179       /* Group all of the pixel store modes that need to be sent to the
180        * server here.  Care must be used to only send modes to the server that
181        * won't affect the size of the data sent to or received from the
182        * server.  GL_PACK_INVERT_MESA is safe in this respect, but other,
183        * future modes may not be.
184        */
185    case GL_PACK_INVERT_MESA:
186       send_PixelStore(gc, X_GLsop_PixelStoref, pname, &param);
187       break;
188 
189    default:
190       __glXSetError(gc, GL_INVALID_ENUM);
191       break;
192    }
193 }
194 
195 void
__indirect_glPixelStorei(GLenum pname,GLint param)196 __indirect_glPixelStorei(GLenum pname, GLint param)
197 {
198    struct glx_context *gc = __glXGetCurrentContext();
199    __GLXattribute *state = gc->client_state_private;
200    Display *dpy = gc->currentDpy;
201 
202    if (!dpy)
203       return;
204 
205    switch (pname) {
206    case GL_PACK_ROW_LENGTH:
207       if (param < 0) {
208          __glXSetError(gc, GL_INVALID_VALUE);
209          return;
210       }
211       state->storePack.rowLength = param;
212       break;
213    case GL_PACK_IMAGE_HEIGHT:
214       if (param < 0) {
215          __glXSetError(gc, GL_INVALID_VALUE);
216          return;
217       }
218       state->storePack.imageHeight = param;
219       break;
220    case GL_PACK_SKIP_ROWS:
221       if (param < 0) {
222          __glXSetError(gc, GL_INVALID_VALUE);
223          return;
224       }
225       state->storePack.skipRows = param;
226       break;
227    case GL_PACK_SKIP_PIXELS:
228       if (param < 0) {
229          __glXSetError(gc, GL_INVALID_VALUE);
230          return;
231       }
232       state->storePack.skipPixels = param;
233       break;
234    case GL_PACK_SKIP_IMAGES:
235       if (param < 0) {
236          __glXSetError(gc, GL_INVALID_VALUE);
237          return;
238       }
239       state->storePack.skipImages = param;
240       break;
241    case GL_PACK_ALIGNMENT:
242       switch (param) {
243       case 1:
244       case 2:
245       case 4:
246       case 8:
247          state->storePack.alignment = param;
248          break;
249       default:
250          __glXSetError(gc, GL_INVALID_VALUE);
251          return;
252       }
253       break;
254    case GL_PACK_SWAP_BYTES:
255       state->storePack.swapEndian = (param != 0);
256       break;
257    case GL_PACK_LSB_FIRST:
258       state->storePack.lsbFirst = (param != 0);
259       break;
260 
261    case GL_UNPACK_ROW_LENGTH:
262       if (param < 0) {
263          __glXSetError(gc, GL_INVALID_VALUE);
264          return;
265       }
266       state->storeUnpack.rowLength = param;
267       break;
268    case GL_UNPACK_IMAGE_HEIGHT:
269       if (param < 0) {
270          __glXSetError(gc, GL_INVALID_VALUE);
271          return;
272       }
273       state->storeUnpack.imageHeight = param;
274       break;
275    case GL_UNPACK_SKIP_ROWS:
276       if (param < 0) {
277          __glXSetError(gc, GL_INVALID_VALUE);
278          return;
279       }
280       state->storeUnpack.skipRows = param;
281       break;
282    case GL_UNPACK_SKIP_PIXELS:
283       if (param < 0) {
284          __glXSetError(gc, GL_INVALID_VALUE);
285          return;
286       }
287       state->storeUnpack.skipPixels = param;
288       break;
289    case GL_UNPACK_SKIP_IMAGES:
290       if (param < 0) {
291          __glXSetError(gc, GL_INVALID_VALUE);
292          return;
293       }
294       state->storeUnpack.skipImages = param;
295       break;
296    case GL_UNPACK_ALIGNMENT:
297       switch (param) {
298       case 1:
299       case 2:
300       case 4:
301       case 8:
302          state->storeUnpack.alignment = param;
303          break;
304       default:
305          __glXSetError(gc, GL_INVALID_VALUE);
306          return;
307       }
308       break;
309    case GL_UNPACK_SWAP_BYTES:
310       state->storeUnpack.swapEndian = (param != 0);
311       break;
312    case GL_UNPACK_LSB_FIRST:
313       state->storeUnpack.lsbFirst = (param != 0);
314       break;
315 
316       /* Group all of the pixel store modes that need to be sent to the
317        * server here.  Care must be used to only send modes to the server that
318        * won't affect the size of the data sent to or received from the
319        * server.  GL_PACK_INVERT_MESA is safe in this respect, but other,
320        * future modes may not be.
321        */
322    case GL_PACK_INVERT_MESA:
323       send_PixelStore(gc, X_GLsop_PixelStorei, pname, &param);
324       break;
325 
326    default:
327       __glXSetError(gc, GL_INVALID_ENUM);
328       break;
329    }
330 }
331