1/* 2 * Mesa 3-D graphics library 3 * Version: 7.1 4 * 5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * 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 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25/** 26 * \file pixelstore.c 27 * glPixelStore functions. 28 */ 29 30 31#include "glheader.h" 32#include "bufferobj.h" 33#include "context.h" 34#include "pixelstore.h" 35#include "mfeatures.h" 36#include "mtypes.h" 37 38 39void GLAPIENTRY 40_mesa_PixelStorei( GLenum pname, GLint param ) 41{ 42 /* NOTE: this call can't be compiled into the display list */ 43 GET_CURRENT_CONTEXT(ctx); 44 ASSERT_OUTSIDE_BEGIN_END(ctx); 45 46 switch (pname) { 47 case GL_PACK_SWAP_BYTES: 48 if (!_mesa_is_desktop_gl(ctx)) 49 goto invalid_enum_error; 50 if (param == (GLint)ctx->Pack.SwapBytes) 51 return; 52 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 53 ctx->Pack.SwapBytes = param ? GL_TRUE : GL_FALSE; 54 break; 55 case GL_PACK_LSB_FIRST: 56 if (!_mesa_is_desktop_gl(ctx)) 57 goto invalid_enum_error; 58 if (param == (GLint)ctx->Pack.LsbFirst) 59 return; 60 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 61 ctx->Pack.LsbFirst = param ? GL_TRUE : GL_FALSE; 62 break; 63 case GL_PACK_ROW_LENGTH: 64 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 65 goto invalid_enum_error; 66 if (param<0) { 67 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); 68 return; 69 } 70 if (ctx->Pack.RowLength == param) 71 return; 72 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 73 ctx->Pack.RowLength = param; 74 break; 75 case GL_PACK_IMAGE_HEIGHT: 76 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 77 goto invalid_enum_error; 78 if (param<0) { 79 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); 80 return; 81 } 82 if (ctx->Pack.ImageHeight == param) 83 return; 84 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 85 ctx->Pack.ImageHeight = param; 86 break; 87 case GL_PACK_SKIP_PIXELS: 88 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 89 goto invalid_enum_error; 90 if (param<0) { 91 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); 92 return; 93 } 94 if (ctx->Pack.SkipPixels == param) 95 return; 96 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 97 ctx->Pack.SkipPixels = param; 98 break; 99 case GL_PACK_SKIP_ROWS: 100 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 101 goto invalid_enum_error; 102 if (param<0) { 103 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); 104 return; 105 } 106 if (ctx->Pack.SkipRows == param) 107 return; 108 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 109 ctx->Pack.SkipRows = param; 110 break; 111 case GL_PACK_SKIP_IMAGES: 112 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 113 goto invalid_enum_error; 114 if (param<0) { 115 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); 116 return; 117 } 118 if (ctx->Pack.SkipImages == param) 119 return; 120 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 121 ctx->Pack.SkipImages = param; 122 break; 123 case GL_PACK_ALIGNMENT: 124 if (param!=1 && param!=2 && param!=4 && param!=8) { 125 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); 126 return; 127 } 128 if (ctx->Pack.Alignment == param) 129 return; 130 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 131 ctx->Pack.Alignment = param; 132 break; 133 case GL_PACK_INVERT_MESA: 134 if (!_mesa_is_desktop_gl(ctx)) 135 goto invalid_enum_error; 136 if (!ctx->Extensions.MESA_pack_invert) { 137 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelstore(pname)" ); 138 return; 139 } 140 if (ctx->Pack.Invert == param) 141 return; 142 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 143 ctx->Pack.Invert = param; 144 break; 145 146 case GL_UNPACK_SWAP_BYTES: 147 if (!_mesa_is_desktop_gl(ctx)) 148 goto invalid_enum_error; 149 if (param == (GLint)ctx->Unpack.SwapBytes) 150 return; 151 if ((GLint)ctx->Unpack.SwapBytes == param) 152 return; 153 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 154 ctx->Unpack.SwapBytes = param ? GL_TRUE : GL_FALSE; 155 break; 156 case GL_UNPACK_LSB_FIRST: 157 if (!_mesa_is_desktop_gl(ctx)) 158 goto invalid_enum_error; 159 if (param == (GLint)ctx->Unpack.LsbFirst) 160 return; 161 if ((GLint)ctx->Unpack.LsbFirst == param) 162 return; 163 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 164 ctx->Unpack.LsbFirst = param ? GL_TRUE : GL_FALSE; 165 break; 166 case GL_UNPACK_ROW_LENGTH: 167 if (ctx->API == API_OPENGLES) 168 goto invalid_enum_error; 169 if (param<0) { 170 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); 171 return; 172 } 173 if (ctx->Unpack.RowLength == param) 174 return; 175 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 176 ctx->Unpack.RowLength = param; 177 break; 178 case GL_UNPACK_IMAGE_HEIGHT: 179 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 180 goto invalid_enum_error; 181 if (param<0) { 182 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); 183 return; 184 } 185 if (ctx->Unpack.ImageHeight == param) 186 return; 187 188 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 189 ctx->Unpack.ImageHeight = param; 190 break; 191 case GL_UNPACK_SKIP_PIXELS: 192 if (ctx->API == API_OPENGLES) 193 goto invalid_enum_error; 194 if (param<0) { 195 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); 196 return; 197 } 198 if (ctx->Unpack.SkipPixels == param) 199 return; 200 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 201 ctx->Unpack.SkipPixels = param; 202 break; 203 case GL_UNPACK_SKIP_ROWS: 204 if (ctx->API == API_OPENGLES) 205 goto invalid_enum_error; 206 if (param<0) { 207 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); 208 return; 209 } 210 if (ctx->Unpack.SkipRows == param) 211 return; 212 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 213 ctx->Unpack.SkipRows = param; 214 break; 215 case GL_UNPACK_SKIP_IMAGES: 216 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 217 goto invalid_enum_error; 218 if (param < 0) { 219 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); 220 return; 221 } 222 if (ctx->Unpack.SkipImages == param) 223 return; 224 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 225 ctx->Unpack.SkipImages = param; 226 break; 227 case GL_UNPACK_ALIGNMENT: 228 if (param!=1 && param!=2 && param!=4 && param!=8) { 229 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore" ); 230 return; 231 } 232 if (ctx->Unpack.Alignment == param) 233 return; 234 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 235 ctx->Unpack.Alignment = param; 236 break; 237 default: 238 goto invalid_enum_error; 239 } 240 241 return; 242 243invalid_enum_error: 244 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelStore" ); 245 return; 246} 247 248 249void GLAPIENTRY 250_mesa_PixelStoref( GLenum pname, GLfloat param ) 251{ 252 _mesa_PixelStorei( pname, IROUND(param) ); 253} 254 255 256 257/** 258 * Initialize the context's pixel store state. 259 */ 260void 261_mesa_init_pixelstore( struct gl_context *ctx ) 262{ 263 /* Pixel transfer */ 264 ctx->Pack.Alignment = 4; 265 ctx->Pack.RowLength = 0; 266 ctx->Pack.ImageHeight = 0; 267 ctx->Pack.SkipPixels = 0; 268 ctx->Pack.SkipRows = 0; 269 ctx->Pack.SkipImages = 0; 270 ctx->Pack.SwapBytes = GL_FALSE; 271 ctx->Pack.LsbFirst = GL_FALSE; 272 ctx->Pack.Invert = GL_FALSE; 273#if FEATURE_EXT_pixel_buffer_object 274 _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj, 275 ctx->Shared->NullBufferObj); 276#endif 277 ctx->Unpack.Alignment = 4; 278 ctx->Unpack.RowLength = 0; 279 ctx->Unpack.ImageHeight = 0; 280 ctx->Unpack.SkipPixels = 0; 281 ctx->Unpack.SkipRows = 0; 282 ctx->Unpack.SkipImages = 0; 283 ctx->Unpack.SwapBytes = GL_FALSE; 284 ctx->Unpack.LsbFirst = GL_FALSE; 285 ctx->Unpack.Invert = GL_FALSE; 286#if FEATURE_EXT_pixel_buffer_object 287 _mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj, 288 ctx->Shared->NullBufferObj); 289#endif 290 291 /* 292 * _mesa_unpack_image() returns image data in this format. When we 293 * execute image commands (glDrawPixels(), glTexImage(), etc) from 294 * within display lists we have to be sure to set the current 295 * unpacking parameters to these values! 296 */ 297 ctx->DefaultPacking.Alignment = 1; 298 ctx->DefaultPacking.RowLength = 0; 299 ctx->DefaultPacking.SkipPixels = 0; 300 ctx->DefaultPacking.SkipRows = 0; 301 ctx->DefaultPacking.ImageHeight = 0; 302 ctx->DefaultPacking.SkipImages = 0; 303 ctx->DefaultPacking.SwapBytes = GL_FALSE; 304 ctx->DefaultPacking.LsbFirst = GL_FALSE; 305 ctx->DefaultPacking.Invert = GL_FALSE; 306#if FEATURE_EXT_pixel_buffer_object 307 _mesa_reference_buffer_object(ctx, &ctx->DefaultPacking.BufferObj, 308 ctx->Shared->NullBufferObj); 309#endif 310} 311