1848b8605Smrg/*
2848b8605Smrg * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3848b8605Smrg * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
4848b8605Smrg *
5848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
6848b8605Smrg * copy of this software and associated documentation files (the "Software"),
7848b8605Smrg * to deal in the Software without restriction, including without limitation
8848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the
10848b8605Smrg * Software is furnished to do so, subject to the following conditions:
11848b8605Smrg *
12848b8605Smrg * The above copyright notice including the dates of first publication and
13848b8605Smrg * either this permission notice or a reference to
14848b8605Smrg * http://oss.sgi.com/projects/FreeB/
15848b8605Smrg * shall be included in all copies or substantial portions of the Software.
16848b8605Smrg *
17848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20848b8605Smrg * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21848b8605Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22848b8605Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23848b8605Smrg * SOFTWARE.
24848b8605Smrg *
25848b8605Smrg * Except as contained in this notice, the name of Silicon Graphics, Inc.
26848b8605Smrg * shall not be used in advertising or otherwise to promote the sale, use or
27848b8605Smrg * other dealings in this Software without prior written authorization from
28848b8605Smrg * Silicon Graphics, Inc.
29848b8605Smrg */
30848b8605Smrg
31848b8605Smrg/*
32848b8605Smrg * (C) Copyright IBM Corporation 2005
33848b8605Smrg * All Rights Reserved.
34848b8605Smrg *
35848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
36848b8605Smrg * copy of this software and associated documentation files (the "Software"),
37848b8605Smrg * to deal in the Software without restriction, including without limitation
38848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sub license,
39848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the
40848b8605Smrg * Software is furnished to do so, subject to the following conditions:
41848b8605Smrg *
42848b8605Smrg * The above copyright notice and this permission notice (including the next
43848b8605Smrg * paragraph) shall be included in all copies or substantial portions of the
44848b8605Smrg * Software.
45848b8605Smrg *
46848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
47848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
48848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
49848b8605Smrg * IBM,
50848b8605Smrg * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
51848b8605Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
52848b8605Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
53848b8605Smrg * SOFTWARE.
54848b8605Smrg */
55848b8605Smrg
56848b8605Smrg#include "packrender.h"
57848b8605Smrg#include "indirect.h"
58848b8605Smrg
59848b8605Smrg/**
60848b8605Smrg * Send a large image to the server.  If necessary, a buffer is allocated
61848b8605Smrg * to hold the unpacked data that is copied from the clients memory.
62848b8605Smrg *
63848b8605Smrg * \param gc        Current GLX context
64848b8605Smrg * \param compsize  Size, in bytes, of the image portion
65848b8605Smrg * \param dim       Number of dimensions of the image
66848b8605Smrg * \param width     Width of the image
67848b8605Smrg * \param height    Height of the image, must be 1 for 1D images
68848b8605Smrg * \param depth     Depth of the image, must be 1 for 1D or 2D images
69848b8605Smrg * \param format    Format of the image
70848b8605Smrg * \param type      Data type of the image
71848b8605Smrg * \param src       Pointer to the image data
72848b8605Smrg * \param pc        Pointer to end of the command header
73848b8605Smrg * \param modes     Pointer to the pixel unpack data
74848b8605Smrg *
75848b8605Smrg * \todo
76848b8605Smrg * Modify this function so that \c NULL images are sent using
77848b8605Smrg * \c __glXSendLargeChunk instead of __glXSendLargeCommand.  Doing this
78848b8605Smrg * will eliminate the need to allocate a buffer for that case.
79848b8605Smrg */
80848b8605Smrgvoid
81848b8605Smrg__glXSendLargeImage(struct glx_context * gc, GLint compsize, GLint dim,
82848b8605Smrg                    GLint width, GLint height, GLint depth,
83848b8605Smrg                    GLenum format, GLenum type, const GLvoid * src,
84848b8605Smrg                    GLubyte * pc, GLubyte * modes)
85848b8605Smrg{
86848b8605Smrg    /* Allocate a temporary holding buffer */
87848b8605Smrg    GLubyte *buf = malloc(compsize);
88848b8605Smrg    if (!buf) {
89848b8605Smrg	__glXSetError(gc, GL_OUT_OF_MEMORY);
90848b8605Smrg	return;
91848b8605Smrg    }
92848b8605Smrg
93848b8605Smrg    /* Apply pixel store unpack modes to copy data into buf */
94848b8605Smrg    if (src != NULL) {
95848b8605Smrg	(*gc->fillImage) (gc, dim, width, height, depth, format, type,
96848b8605Smrg			  src, buf, modes);
97848b8605Smrg    }
98848b8605Smrg    else {
99848b8605Smrg	if (dim < 3) {
100848b8605Smrg	    (void) memcpy(modes, __glXDefaultPixelStore + 4, 20);
101848b8605Smrg	}
102848b8605Smrg	else {
103848b8605Smrg	    (void) memcpy(modes, __glXDefaultPixelStore + 0, 36);
104848b8605Smrg	}
105848b8605Smrg    }
106848b8605Smrg
107848b8605Smrg    /* Send large command */
108848b8605Smrg    __glXSendLargeCommand(gc, gc->pc, pc - gc->pc, buf, compsize);
109848b8605Smrg
110848b8605Smrg    /* Free buffer */
111848b8605Smrg    free((char *) buf);
112848b8605Smrg}
113848b8605Smrg
114848b8605Smrg/************************************************************************/
115848b8605Smrg
116848b8605Smrg/**
117848b8605Smrg * Implement GLX protocol for \c glSeparableFilter2D.
118848b8605Smrg */
119848b8605Smrgvoid
120848b8605Smrg__indirect_glSeparableFilter2D(GLenum target, GLenum internalformat,
121848b8605Smrg                               GLsizei width, GLsizei height, GLenum format,
122848b8605Smrg                               GLenum type, const GLvoid * row,
123848b8605Smrg                               const GLvoid * column)
124848b8605Smrg{
125848b8605Smrg   __GLX_DECLARE_VARIABLES();
126848b8605Smrg   GLuint compsize2, hdrlen, totalhdrlen, image1len, image2len;
127848b8605Smrg
128848b8605Smrg   __GLX_LOAD_VARIABLES();
129848b8605Smrg   compsize = __glImageSize(width, 1, 1, format, type, 0);
130848b8605Smrg   compsize2 = __glImageSize(height, 1, 1, format, type, 0);
131848b8605Smrg   totalhdrlen = __GLX_PAD(__GLX_CONV_FILT_CMD_HDR_SIZE);
132848b8605Smrg   hdrlen = __GLX_PAD(__GLX_CONV_FILT_HDR_SIZE);
133848b8605Smrg   image1len = __GLX_PAD(compsize);
134848b8605Smrg   image2len = __GLX_PAD(compsize2);
135848b8605Smrg   cmdlen = totalhdrlen + image1len + image2len;
136848b8605Smrg   if (!gc->currentDpy)
137848b8605Smrg      return;
138848b8605Smrg
139848b8605Smrg   if (cmdlen <= gc->maxSmallRenderCommandSize) {
140848b8605Smrg      /* Use GLXRender protocol to send small command */
141848b8605Smrg      __GLX_BEGIN_VARIABLE_WITH_PIXEL(X_GLrop_SeparableFilter2D, cmdlen);
142848b8605Smrg      __GLX_PUT_LONG(0, target);
143848b8605Smrg      __GLX_PUT_LONG(4, internalformat);
144848b8605Smrg      __GLX_PUT_LONG(8, width);
145848b8605Smrg      __GLX_PUT_LONG(12, height);
146848b8605Smrg      __GLX_PUT_LONG(16, format);
147848b8605Smrg      __GLX_PUT_LONG(20, type);
148848b8605Smrg      pc += hdrlen;
149848b8605Smrg      if (compsize > 0) {
150848b8605Smrg         (*gc->fillImage) (gc, 1, width, 1, 1, format, type,
151848b8605Smrg                           row, pc, pixelHeaderPC);
152848b8605Smrg         pc += image1len;
153848b8605Smrg      }
154848b8605Smrg      if (compsize2 > 0) {
155848b8605Smrg         (*gc->fillImage) (gc, 1, height, 1, 1, format, type,
156848b8605Smrg                           column, pc, NULL);
157848b8605Smrg         pc += image2len;
158848b8605Smrg      }
159848b8605Smrg      if ((compsize == 0) && (compsize2 == 0)) {
160848b8605Smrg         /* Setup default store modes */
161848b8605Smrg         (void) memcpy(pixelHeaderPC, __glXDefaultPixelStore + 4, 20);
162848b8605Smrg      }
163848b8605Smrg      __GLX_END(0);
164848b8605Smrg   }
165848b8605Smrg   else {
166848b8605Smrg      GLubyte *buf;
167848b8605Smrg      const GLint bufsize = image1len + image2len;
168848b8605Smrg
169848b8605Smrg      /* Use GLXRenderLarge protocol to send command */
170848b8605Smrg      __GLX_BEGIN_VARIABLE_LARGE_WITH_PIXEL(X_GLrop_SeparableFilter2D,
171848b8605Smrg                                            cmdlen + 4);
172848b8605Smrg      __GLX_PUT_LONG(0, target);
173848b8605Smrg      __GLX_PUT_LONG(4, internalformat);
174848b8605Smrg      __GLX_PUT_LONG(8, width);
175848b8605Smrg      __GLX_PUT_LONG(12, height);
176848b8605Smrg      __GLX_PUT_LONG(16, format);
177848b8605Smrg      __GLX_PUT_LONG(20, type);
178848b8605Smrg      pc += hdrlen;
179848b8605Smrg
180848b8605Smrg      /* Allocate a temporary holding buffer */
181848b8605Smrg      buf = malloc(bufsize);
182848b8605Smrg      if (!buf) {
183848b8605Smrg         __glXSetError(gc, GL_OUT_OF_MEMORY);
184848b8605Smrg         return;
185848b8605Smrg      }
186848b8605Smrg      (*gc->fillImage) (gc, 1, width, 1, 1, format, type, row, buf,
187848b8605Smrg                        pixelHeaderPC);
188848b8605Smrg
189848b8605Smrg      (*gc->fillImage) (gc, 1, height, 1, 1, format, type, column,
190848b8605Smrg                        buf + image1len, pixelHeaderPC);
191848b8605Smrg
192848b8605Smrg      /* Send large command */
193848b8605Smrg      __glXSendLargeCommand(gc, gc->pc, (GLint) (pc - gc->pc), buf,
194848b8605Smrg                            bufsize);
195848b8605Smrg      /* Free buffer */
196848b8605Smrg      free((char *) buf);
197848b8605Smrg   }
198848b8605Smrg}
199