2 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
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:
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.
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
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.
31 #ifdef HAVE_DIX_CONFIG_H
32 #include <dix-config.h>
36 #include "glxserver.h"
37 #include "GL/glxproto.h"
39 #include "indirect_size.h"
40 #include "indirect_reqsize.h"
43 (((a & 0xff000000U)>>24) | ((a & 0xff0000U)>>8) | \
44 ((a & 0xff00U)<<8) | ((a & 0xffU)<<24))
46 static int Map1Size( GLint k, GLint order)
48 if (order <= 0 || k < 0) return -1;
52 int __glXMap1dReqSize( const GLbyte *pc, Bool swap )
57 target = *(GLenum*) (pc + 16);
58 order = *(GLint*) (pc + 20);
60 target = SWAPL( target );
61 order = SWAPL( order );
63 k = __glMap1d_size( target );
64 return 8 * Map1Size( k, order );
67 int __glXMap1fReqSize( const GLbyte *pc, Bool swap )
72 target = *(GLenum *)(pc + 0);
73 order = *(GLint *)(pc + 12);
75 target = SWAPL( target );
76 order = SWAPL( order );
78 k = __glMap1f_size(target);
79 return 4 * Map1Size(k, order);
82 static int Map2Size(int k, int majorOrder, int minorOrder)
84 if (majorOrder <= 0 || minorOrder <= 0 || k < 0) return -1;
85 return k * majorOrder * minorOrder;
88 int __glXMap2dReqSize( const GLbyte *pc, Bool swap )
91 GLint uorder, vorder, k;
93 target = *(GLenum *)(pc + 32);
94 uorder = *(GLint *)(pc + 36);
95 vorder = *(GLint *)(pc + 40);
97 target = SWAPL( target );
98 uorder = SWAPL( uorder );
99 vorder = SWAPL( vorder );
101 k = __glMap2d_size( target );
102 return 8 * Map2Size( k, uorder, vorder );
105 int __glXMap2fReqSize( const GLbyte *pc, Bool swap )
108 GLint uorder, vorder, k;
110 target = *(GLenum *)(pc + 0);
111 uorder = *(GLint *)(pc + 12);
112 vorder = *(GLint *)(pc + 24);
114 target = SWAPL( target );
115 uorder = SWAPL( uorder );
116 vorder = SWAPL( vorder );
118 k = __glMap2f_size( target );
119 return 4 * Map2Size( k, uorder, vorder );
123 * Calculate the size of an image.
125 * The size of an image sent to the server from the client or sent from the
126 * server to the client is calculated. The size is based on the dimensions
127 * of the image, the type of pixel data, padding in the image, and the
128 * alignment requirements of the image.
130 * \param format Format of the pixels. Same as the \c format parameter
132 * \param type Type of the pixel data. Same as the \c type parameter
134 * \param target Typically the texture target of the image. If the
135 * target is one of \c GL_PROXY_*, the size returned is
136 * always zero. For uses that do not have a texture target
137 * (e.g, glDrawPixels), zero should be specified.
138 * \param w Width of the image data. Must be >= 1.
139 * \param h Height of the image data. Must be >= 1, even for 1D
141 * \param d Depth of the image data. Must be >= 1, even for 1D or
143 * \param imageHeight If non-zero, defines the true height of a volumetric
144 * image. This value will be used instead of \c h for
145 * calculating the size of the image.
146 * \param rowLength If non-zero, defines the true width of an image. This
147 * value will be used instead of \c w for calculating the
149 * \param skipImages Number of extra layers of image data in a volumtric
150 * image that are to be skipped before the real data.
151 * \param skipRows Number of extra rows of image data in an image that are
152 * to be skipped before the real data.
153 * \param alignment Specifies the alignment for the start of each pixel row
154 * in memory. This value must be one of 1, 2, 4, or 8.
157 * The size of the image is returned. If the specified \c format and \c type
158 * are invalid, -1 is returned. If \c target is one of \c GL_PROXY_*, zero
161 int __glXImageSize( GLenum format, GLenum type, GLenum target,
162 GLsizei w, GLsizei h, GLsizei d,
163 GLint imageHeight, GLint rowLength,
164 GLint skipImages, GLint skipRows, GLint alignment )
166 GLint bytesPerElement, elementsPerGroup, groupsPerRow;
167 GLint groupSize, rowSize, padding, imageSize;
169 if (w < 0 || h < 0 || d < 0 ||
170 (type == GL_BITMAP &&
171 (format != GL_COLOR_INDEX && format != GL_STENCIL_INDEX))) {
174 if (w==0 || h==0 || d == 0) return 0;
177 case GL_PROXY_TEXTURE_1D:
178 case GL_PROXY_TEXTURE_2D:
179 case GL_PROXY_TEXTURE_3D:
180 case GL_PROXY_TEXTURE_4D_SGIS:
181 case GL_PROXY_TEXTURE_CUBE_MAP:
182 case GL_PROXY_TEXTURE_RECTANGLE_ARB:
183 case GL_PROXY_HISTOGRAM:
184 case GL_PROXY_COLOR_TABLE:
185 case GL_PROXY_TEXTURE_COLOR_TABLE_SGI:
186 case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE:
187 case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE:
188 case GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP:
192 if (type == GL_BITMAP) {
194 groupsPerRow = rowLength;
198 rowSize = bits_to_bytes(groupsPerRow);
199 padding = (rowSize % alignment);
201 rowSize += alignment - padding;
203 return ((h + skipRows) * rowSize);
207 case GL_STENCIL_INDEX:
208 case GL_DEPTH_COMPONENT:
215 elementsPerGroup = 1;
219 case GL_422_AVERAGE_EXT:
220 case GL_422_REV_AVERAGE_EXT:
221 case GL_DEPTH_STENCIL_NV:
222 case GL_DEPTH_STENCIL_MESA:
224 case GL_LUMINANCE_ALPHA:
225 elementsPerGroup = 2;
229 elementsPerGroup = 3;
234 elementsPerGroup = 4;
240 case GL_UNSIGNED_BYTE:
244 case GL_UNSIGNED_BYTE_3_3_2:
245 case GL_UNSIGNED_BYTE_2_3_3_REV:
247 elementsPerGroup = 1;
249 case GL_UNSIGNED_SHORT:
253 case GL_UNSIGNED_SHORT_5_6_5:
254 case GL_UNSIGNED_SHORT_5_6_5_REV:
255 case GL_UNSIGNED_SHORT_4_4_4_4:
256 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
257 case GL_UNSIGNED_SHORT_5_5_5_1:
258 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
259 case GL_UNSIGNED_SHORT_8_8_APPLE:
260 case GL_UNSIGNED_SHORT_8_8_REV_APPLE:
261 case GL_UNSIGNED_SHORT_15_1_MESA:
262 case GL_UNSIGNED_SHORT_1_15_REV_MESA:
264 elementsPerGroup = 1;
267 case GL_UNSIGNED_INT:
271 case GL_UNSIGNED_INT_8_8_8_8:
272 case GL_UNSIGNED_INT_8_8_8_8_REV:
273 case GL_UNSIGNED_INT_10_10_10_2:
274 case GL_UNSIGNED_INT_2_10_10_10_REV:
275 case GL_UNSIGNED_INT_24_8_NV:
276 case GL_UNSIGNED_INT_24_8_MESA:
277 case GL_UNSIGNED_INT_8_24_REV_MESA:
279 elementsPerGroup = 1;
284 groupSize = bytesPerElement * elementsPerGroup;
286 groupsPerRow = rowLength;
290 rowSize = groupsPerRow * groupSize;
291 padding = (rowSize % alignment);
293 rowSize += alignment - padding;
295 if (imageHeight > 0) {
296 imageSize = (imageHeight + skipRows) * rowSize;
298 imageSize = (h + skipRows) * rowSize;
300 return ((d + skipImages) * imageSize);
305 /* XXX this is used elsewhere - should it be exported from glxserver.h? */
306 int __glXTypeSize(GLenum enm)
309 case GL_BYTE: return sizeof(GLbyte);
310 case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
311 case GL_SHORT: return sizeof(GLshort);
312 case GL_UNSIGNED_SHORT: return sizeof(GLushort);
313 case GL_INT: return sizeof(GLint);
314 case GL_UNSIGNED_INT: return sizeof(GLint);
315 case GL_FLOAT: return sizeof(GLfloat);
316 case GL_DOUBLE: return sizeof(GLdouble);
321 int __glXDrawArraysReqSize( const GLbyte *pc, Bool swap )
323 __GLXdispatchDrawArraysHeader *hdr = (__GLXdispatchDrawArraysHeader *) pc;
324 __GLXdispatchDrawArraysComponentHeader *compHeader;
325 GLint numVertexes = hdr->numVertexes;
326 GLint numComponents = hdr->numComponents;
327 GLint arrayElementSize = 0;
331 numVertexes = SWAPL( numVertexes );
332 numComponents = SWAPL( numComponents );
335 pc += sizeof(__GLXdispatchDrawArraysHeader);
336 compHeader = (__GLXdispatchDrawArraysComponentHeader *) pc;
338 for (i=0; i<numComponents; i++) {
339 GLenum datatype = compHeader[i].datatype;
340 GLint numVals = compHeader[i].numVals;
341 GLint component = compHeader[i].component;
344 datatype = SWAPL( datatype );
345 numVals = SWAPL( numVals );
346 component = SWAPL( component );
350 case GL_VERTEX_ARRAY:
352 case GL_TEXTURE_COORD_ARRAY:
354 case GL_SECONDARY_COLOR_ARRAY:
355 case GL_NORMAL_ARRAY:
361 case GL_FOG_COORD_ARRAY:
368 case GL_EDGE_FLAG_ARRAY:
369 if ((numVals != 1) && (datatype != GL_UNSIGNED_BYTE)) {
370 /* bad size or bad type */
375 /* unknown component type */
379 arrayElementSize += __GLX_PAD(numVals * __glXTypeSize(datatype));
381 pc += sizeof(__GLXdispatchDrawArraysComponentHeader);
384 return ((numComponents * sizeof(__GLXdispatchDrawArraysComponentHeader)) +
385 (numVertexes * arrayElementSize));
388 int __glXSeparableFilter2DReqSize( const GLbyte *pc, Bool swap )
390 __GLXdispatchConvolutionFilterHeader *hdr =
391 (__GLXdispatchConvolutionFilterHeader *) pc;
393 GLint image1size, image2size;
394 GLenum format = hdr->format;
395 GLenum type = hdr->type;
396 GLint w = hdr->width;
397 GLint h = hdr->height;
398 GLint rowLength = hdr->rowLength;
399 GLint alignment = hdr->alignment;
402 format = SWAPL( format );
403 type = SWAPL( type );
406 rowLength = SWAPL( rowLength );
407 alignment = SWAPL( alignment );
410 /* XXX Should rowLength be used for either or both image? */
411 image1size = __glXImageSize( format, type, 0, w, 1, 1,
412 0, rowLength, 0, 0, alignment );
413 image1size = __GLX_PAD(image1size);
414 image2size = __glXImageSize( format, type, 0, h, 1, 1,
415 0, rowLength, 0, 0, alignment );
416 return image1size + image2size;