rensize.c revision 6747b715
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#ifdef HAVE_DIX_CONFIG_H 32#include <dix-config.h> 33#endif 34 35#include <GL/gl.h> 36#include "glxserver.h" 37#include "GL/glxproto.h" 38#include "unpack.h" 39#include "indirect_size.h" 40#include "indirect_reqsize.h" 41 42#define SWAPL(a) \ 43 (((a & 0xff000000U)>>24) | ((a & 0xff0000U)>>8) | \ 44 ((a & 0xff00U)<<8) | ((a & 0xffU)<<24)) 45 46static int Map1Size( GLint k, GLint order) 47{ 48 if (order <= 0 || k < 0) return -1; 49 return k * order; 50} 51 52int __glXMap1dReqSize( const GLbyte *pc, Bool swap ) 53{ 54 GLenum target; 55 GLint order, k; 56 57 target = *(GLenum*) (pc + 16); 58 order = *(GLint*) (pc + 20); 59 if (swap) { 60 target = SWAPL( target ); 61 order = SWAPL( order ); 62 } 63 k = __glMap1d_size( target ); 64 return 8 * Map1Size( k, order ); 65} 66 67int __glXMap1fReqSize( const GLbyte *pc, Bool swap ) 68{ 69 GLenum target; 70 GLint order, k; 71 72 target = *(GLenum *)(pc + 0); 73 order = *(GLint *)(pc + 12); 74 if (swap) { 75 target = SWAPL( target ); 76 order = SWAPL( order ); 77 } 78 k = __glMap1f_size(target); 79 return 4 * Map1Size(k, order); 80} 81 82static int Map2Size(int k, int majorOrder, int minorOrder) 83{ 84 if (majorOrder <= 0 || minorOrder <= 0 || k < 0) return -1; 85 return k * majorOrder * minorOrder; 86} 87 88int __glXMap2dReqSize( const GLbyte *pc, Bool swap ) 89{ 90 GLenum target; 91 GLint uorder, vorder, k; 92 93 target = *(GLenum *)(pc + 32); 94 uorder = *(GLint *)(pc + 36); 95 vorder = *(GLint *)(pc + 40); 96 if (swap) { 97 target = SWAPL( target ); 98 uorder = SWAPL( uorder ); 99 vorder = SWAPL( vorder ); 100 } 101 k = __glMap2d_size( target ); 102 return 8 * Map2Size( k, uorder, vorder ); 103} 104 105int __glXMap2fReqSize( const GLbyte *pc, Bool swap ) 106{ 107 GLenum target; 108 GLint uorder, vorder, k; 109 110 target = *(GLenum *)(pc + 0); 111 uorder = *(GLint *)(pc + 12); 112 vorder = *(GLint *)(pc + 24); 113 if (swap) { 114 target = SWAPL( target ); 115 uorder = SWAPL( uorder ); 116 vorder = SWAPL( vorder ); 117 } 118 k = __glMap2f_size( target ); 119 return 4 * Map2Size( k, uorder, vorder ); 120} 121 122/** 123 * Calculate the size of an image. 124 * 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. 129 * 130 * \param format Format of the pixels. Same as the \c format parameter 131 * to \c glTexImage1D 132 * \param type Type of the pixel data. Same as the \c type parameter 133 * to \c glTexImage1D 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 140 * images. 141 * \param d Depth of the image data. Must be >= 1, even for 1D or 142 * 2D images. 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 148 * size of the image. 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. 155 * 156 * \returns 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 159 * is returned. 160 */ 161int __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 ) 165{ 166 GLint bytesPerElement, elementsPerGroup, groupsPerRow; 167 GLint groupSize, rowSize, padding, imageSize; 168 169 if (w < 0 || h < 0 || d < 0 || 170 (type == GL_BITMAP && 171 (format != GL_COLOR_INDEX && format != GL_STENCIL_INDEX))) { 172 return -1; 173 } 174 if (w==0 || h==0 || d == 0) return 0; 175 176 switch( target ) { 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: 189 return 0; 190 } 191 192 if (type == GL_BITMAP) { 193 if (rowLength > 0) { 194 groupsPerRow = rowLength; 195 } else { 196 groupsPerRow = w; 197 } 198 rowSize = bits_to_bytes(groupsPerRow); 199 padding = (rowSize % alignment); 200 if (padding) { 201 rowSize += alignment - padding; 202 } 203 return ((h + skipRows) * rowSize); 204 } else { 205 switch(format) { 206 case GL_COLOR_INDEX: 207 case GL_STENCIL_INDEX: 208 case GL_DEPTH_COMPONENT: 209 case GL_RED: 210 case GL_GREEN: 211 case GL_BLUE: 212 case GL_ALPHA: 213 case GL_LUMINANCE: 214 case GL_INTENSITY: 215 elementsPerGroup = 1; 216 break; 217 case GL_422_EXT: 218 case GL_422_REV_EXT: 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: 223 case GL_YCBCR_MESA: 224 case GL_LUMINANCE_ALPHA: 225 elementsPerGroup = 2; 226 break; 227 case GL_RGB: 228 case GL_BGR: 229 elementsPerGroup = 3; 230 break; 231 case GL_RGBA: 232 case GL_BGRA: 233 case GL_ABGR_EXT: 234 elementsPerGroup = 4; 235 break; 236 default: 237 return -1; 238 } 239 switch(type) { 240 case GL_UNSIGNED_BYTE: 241 case GL_BYTE: 242 bytesPerElement = 1; 243 break; 244 case GL_UNSIGNED_BYTE_3_3_2: 245 case GL_UNSIGNED_BYTE_2_3_3_REV: 246 bytesPerElement = 1; 247 elementsPerGroup = 1; 248 break; 249 case GL_UNSIGNED_SHORT: 250 case GL_SHORT: 251 bytesPerElement = 2; 252 break; 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: 263 bytesPerElement = 2; 264 elementsPerGroup = 1; 265 break; 266 case GL_INT: 267 case GL_UNSIGNED_INT: 268 case GL_FLOAT: 269 bytesPerElement = 4; 270 break; 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: 278 bytesPerElement = 4; 279 elementsPerGroup = 1; 280 break; 281 default: 282 return -1; 283 } 284 groupSize = bytesPerElement * elementsPerGroup; 285 if (rowLength > 0) { 286 groupsPerRow = rowLength; 287 } else { 288 groupsPerRow = w; 289 } 290 rowSize = groupsPerRow * groupSize; 291 padding = (rowSize % alignment); 292 if (padding) { 293 rowSize += alignment - padding; 294 } 295 if (imageHeight > 0) { 296 imageSize = (imageHeight + skipRows) * rowSize; 297 } else { 298 imageSize = (h + skipRows) * rowSize; 299 } 300 return ((d + skipImages) * imageSize); 301 } 302} 303 304 305/* XXX this is used elsewhere - should it be exported from glxserver.h? */ 306int __glXTypeSize(GLenum enm) 307{ 308 switch(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); 317 default: return -1; 318 } 319} 320 321int __glXDrawArraysReqSize( const GLbyte *pc, Bool swap ) 322{ 323 __GLXdispatchDrawArraysHeader *hdr = (__GLXdispatchDrawArraysHeader *) pc; 324 __GLXdispatchDrawArraysComponentHeader *compHeader; 325 GLint numVertexes = hdr->numVertexes; 326 GLint numComponents = hdr->numComponents; 327 GLint arrayElementSize = 0; 328 int i; 329 330 if (swap) { 331 numVertexes = SWAPL( numVertexes ); 332 numComponents = SWAPL( numComponents ); 333 } 334 335 pc += sizeof(__GLXdispatchDrawArraysHeader); 336 compHeader = (__GLXdispatchDrawArraysComponentHeader *) pc; 337 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; 342 343 if (swap) { 344 datatype = SWAPL( datatype ); 345 numVals = SWAPL( numVals ); 346 component = SWAPL( component ); 347 } 348 349 switch (component) { 350 case GL_VERTEX_ARRAY: 351 case GL_COLOR_ARRAY: 352 case GL_TEXTURE_COORD_ARRAY: 353 break; 354 case GL_SECONDARY_COLOR_ARRAY: 355 case GL_NORMAL_ARRAY: 356 if (numVals != 3) { 357 /* bad size */ 358 return -1; 359 } 360 break; 361 case GL_FOG_COORD_ARRAY: 362 case GL_INDEX_ARRAY: 363 if (numVals != 1) { 364 /* bad size */ 365 return -1; 366 } 367 break; 368 case GL_EDGE_FLAG_ARRAY: 369 if ((numVals != 1) && (datatype != GL_UNSIGNED_BYTE)) { 370 /* bad size or bad type */ 371 return -1; 372 } 373 break; 374 default: 375 /* unknown component type */ 376 return -1; 377 } 378 379 arrayElementSize += __GLX_PAD(numVals * __glXTypeSize(datatype)); 380 381 pc += sizeof(__GLXdispatchDrawArraysComponentHeader); 382 } 383 384 return ((numComponents * sizeof(__GLXdispatchDrawArraysComponentHeader)) + 385 (numVertexes * arrayElementSize)); 386} 387 388int __glXSeparableFilter2DReqSize( const GLbyte *pc, Bool swap ) 389{ 390 __GLXdispatchConvolutionFilterHeader *hdr = 391 (__GLXdispatchConvolutionFilterHeader *) pc; 392 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; 400 401 if (swap) { 402 format = SWAPL( format ); 403 type = SWAPL( type ); 404 w = SWAPL( w ); 405 h = SWAPL( h ); 406 rowLength = SWAPL( rowLength ); 407 alignment = SWAPL( alignment ); 408 } 409 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; 417 418} 419