xref: /aosp_15_r20/external/mesa3d/src/glx/renderpix.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 /*
9  * (C) Copyright IBM Corporation 2005
10  * All Rights Reserved.
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a
13  * copy of this software and associated documentation files (the "Software"),
14  * to deal in the Software without restriction, including without limitation
15  * the rights to use, copy, modify, merge, publish, distribute, sub license,
16  * and/or sell copies of the Software, and to permit persons to whom the
17  * Software is furnished to do so, subject to the following conditions:
18  *
19  * The above copyright notice and this permission notice (including the next
20  * paragraph) shall be included in all copies or substantial portions of the
21  * Software.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
26  * IBM,
27  * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
28  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
29  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30  * SOFTWARE.
31  */
32 
33 #include "packrender.h"
34 #include "indirect.h"
35 
36 /**
37  * Send a large image to the server.  If necessary, a buffer is allocated
38  * to hold the unpacked data that is copied from the clients memory.
39  *
40  * \param gc        Current GLX context
41  * \param compsize  Size, in bytes, of the image portion
42  * \param dim       Number of dimensions of the image
43  * \param width     Width of the image
44  * \param height    Height of the image, must be 1 for 1D images
45  * \param depth     Depth of the image, must be 1 for 1D or 2D images
46  * \param format    Format of the image
47  * \param type      Data type of the image
48  * \param src       Pointer to the image data
49  * \param pc        Pointer to end of the command header
50  * \param modes     Pointer to the pixel unpack data
51  *
52  * \todo
53  * Modify this function so that \c NULL images are sent using
54  * \c __glXSendLargeChunk instead of __glXSendLargeCommand.  Doing this
55  * will eliminate the need to allocate a buffer for that case.
56  */
57 void
__glXSendLargeImage(struct glx_context * gc,GLint compsize,GLint dim,GLint width,GLint height,GLint depth,GLenum format,GLenum type,const GLvoid * src,GLubyte * pc,GLubyte * modes)58 __glXSendLargeImage(struct glx_context * gc, GLint compsize, GLint dim,
59                     GLint width, GLint height, GLint depth,
60                     GLenum format, GLenum type, const GLvoid * src,
61                     GLubyte * pc, GLubyte * modes)
62 {
63     /* Allocate a temporary holding buffer */
64     GLubyte *buf = malloc(compsize);
65     if (!buf) {
66    __glXSetError(gc, GL_OUT_OF_MEMORY);
67    return;
68     }
69 
70     /* Apply pixel store unpack modes to copy data into buf */
71     if (src != NULL) {
72    __glFillImage(gc, dim, width, height, depth, format, type,
73                       src, buf, modes);
74     }
75     else {
76    if (dim < 3) {
77        (void) memcpy(modes, __glXDefaultPixelStore + 4, 20);
78    }
79    else {
80        (void) memcpy(modes, __glXDefaultPixelStore + 0, 36);
81    }
82     }
83 
84     /* Send large command */
85     __glXSendLargeCommand(gc, gc->pc, pc - gc->pc, buf, compsize);
86 
87     /* Free buffer */
88     free((char *) buf);
89 }
90 
91 /************************************************************************/
92 
93 /**
94  * Implement GLX protocol for \c glSeparableFilter2D.
95  */
96 void
__indirect_glSeparableFilter2D(GLenum target,GLenum internalformat,GLsizei width,GLsizei height,GLenum format,GLenum type,const GLvoid * row,const GLvoid * column)97 __indirect_glSeparableFilter2D(GLenum target, GLenum internalformat,
98                                GLsizei width, GLsizei height, GLenum format,
99                                GLenum type, const GLvoid * row,
100                                const GLvoid * column)
101 {
102    __GLX_DECLARE_VARIABLES();
103    GLuint compsize2, hdrlen, totalhdrlen, image1len, image2len;
104 
105    __GLX_LOAD_VARIABLES();
106    compsize = __glImageSize(width, 1, 1, format, type, 0);
107    compsize2 = __glImageSize(height, 1, 1, format, type, 0);
108    totalhdrlen = __GLX_PAD(__GLX_CONV_FILT_CMD_HDR_SIZE);
109    hdrlen = __GLX_PAD(__GLX_CONV_FILT_HDR_SIZE);
110    image1len = __GLX_PAD(compsize);
111    image2len = __GLX_PAD(compsize2);
112    cmdlen = totalhdrlen + image1len + image2len;
113    if (!gc->currentDpy)
114       return;
115 
116    if (cmdlen <= gc->maxSmallRenderCommandSize) {
117       /* Use GLXRender protocol to send small command */
118       __GLX_BEGIN_VARIABLE_WITH_PIXEL(X_GLrop_SeparableFilter2D, cmdlen);
119       __GLX_PUT_LONG(0, target);
120       __GLX_PUT_LONG(4, internalformat);
121       __GLX_PUT_LONG(8, width);
122       __GLX_PUT_LONG(12, height);
123       __GLX_PUT_LONG(16, format);
124       __GLX_PUT_LONG(20, type);
125       pc += hdrlen;
126       if (compsize > 0) {
127          __glFillImage(gc, 1, width, 1, 1, format, type, row, pc,
128                        pixelHeaderPC);
129          pc += image1len;
130       }
131       if (compsize2 > 0) {
132          __glFillImage(gc, 1, height, 1, 1, format, type, column, pc, NULL);
133          pc += image2len;
134       }
135       if ((compsize == 0) && (compsize2 == 0)) {
136          /* Setup default store modes */
137          (void) memcpy(pixelHeaderPC, __glXDefaultPixelStore + 4, 20);
138       }
139       __GLX_END(0);
140    }
141    else {
142       GLubyte *buf;
143       const GLint bufsize = image1len + image2len;
144 
145       /* Use GLXRenderLarge protocol to send command */
146       __GLX_BEGIN_VARIABLE_LARGE_WITH_PIXEL(X_GLrop_SeparableFilter2D,
147                                             cmdlen + 4);
148       __GLX_PUT_LONG(0, target);
149       __GLX_PUT_LONG(4, internalformat);
150       __GLX_PUT_LONG(8, width);
151       __GLX_PUT_LONG(12, height);
152       __GLX_PUT_LONG(16, format);
153       __GLX_PUT_LONG(20, type);
154       pc += hdrlen;
155 
156       /* Allocate a temporary holding buffer */
157       buf = malloc(bufsize);
158       if (!buf) {
159          __glXSetError(gc, GL_OUT_OF_MEMORY);
160          return;
161       }
162       __glFillImage(gc, 1, width, 1, 1, format, type, row, buf,
163                     pixelHeaderPC);
164 
165       __glFillImage(gc, 1, height, 1, 1, format, type, column,
166                     buf + image1len, pixelHeaderPC);
167 
168       /* Send large command */
169       __glXSendLargeCommand(gc, gc->pc, (GLint) (pc - gc->pc), buf,
170                             bufsize);
171       /* Free buffer */
172       free((char *) buf);
173    }
174 }
175