Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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