Home | History | Annotate | Download | only in main
      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 
     39 void 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 
    243 invalid_enum_error:
    244    _mesa_error( ctx, GL_INVALID_ENUM, "glPixelStore" );
    245    return;
    246 }
    247 
    248 
    249 void 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  */
    260 void
    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