Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 1999-2007  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. #include "main/glheader.h"
  27. #include "main/context.h"
  28. #include "main/mtypes.h"
  29. #include "main/scissor.h"
  30.  
  31.  
  32. /**
  33.  * Set scissor rectangle data directly in ScissorArray
  34.  *
  35.  * This is an internal function that performs no error checking on the
  36.  * supplied data.  It also does \b not call \c dd_function_table::Scissor.
  37.  *
  38.  * \sa _mesa_set_scissor
  39.  */
  40. static void
  41. set_scissor_no_notify(struct gl_context *ctx, unsigned idx,
  42.                       GLint x, GLint y, GLsizei width, GLsizei height)
  43. {
  44.    if (x == ctx->Scissor.ScissorArray[idx].X &&
  45.        y == ctx->Scissor.ScissorArray[idx].Y &&
  46.        width == ctx->Scissor.ScissorArray[idx].Width &&
  47.        height == ctx->Scissor.ScissorArray[idx].Height)
  48.       return;
  49.  
  50.    FLUSH_VERTICES(ctx, _NEW_SCISSOR);
  51.    ctx->Scissor.ScissorArray[idx].X = x;
  52.    ctx->Scissor.ScissorArray[idx].Y = y;
  53.    ctx->Scissor.ScissorArray[idx].Width = width;
  54.    ctx->Scissor.ScissorArray[idx].Height = height;
  55. }
  56.  
  57. /**
  58.  * Called via glScissor
  59.  */
  60. void GLAPIENTRY
  61. _mesa_Scissor( GLint x, GLint y, GLsizei width, GLsizei height )
  62. {
  63.    unsigned i;
  64.    GET_CURRENT_CONTEXT(ctx);
  65.  
  66.    if (MESA_VERBOSE & VERBOSE_API)
  67.       _mesa_debug(ctx, "glScissor %d %d %d %d\n", x, y, width, height);
  68.  
  69.    if (width < 0 || height < 0) {
  70.       _mesa_error( ctx, GL_INVALID_VALUE, "glScissor" );
  71.       return;
  72.    }
  73.  
  74.    /* The GL_ARB_viewport_array spec says:
  75.     *
  76.     *     "Scissor sets the scissor rectangle for all viewports to the same
  77.     *     values and is equivalent (assuming no errors are generated) to:
  78.     *
  79.     *     for (uint i = 0; i < MAX_VIEWPORTS; i++) {
  80.     *         ScissorIndexed(i, left, bottom, width, height);
  81.     *     }"
  82.     *
  83.     * Set the scissor rectangle for all of the viewports supported by the
  84.     * implementation, but only signal the driver once at the end.
  85.     */
  86.    for (i = 0; i < ctx->Const.MaxViewports; i++)
  87.       set_scissor_no_notify(ctx, i, x, y, width, height);
  88.  
  89.    if (ctx->Driver.Scissor)
  90.       ctx->Driver.Scissor(ctx);
  91. }
  92.  
  93.  
  94. /**
  95.  * Define the scissor box.
  96.  *
  97.  * \param x, y coordinates of the scissor box lower-left corner.
  98.  * \param width width of the scissor box.
  99.  * \param height height of the scissor box.
  100.  *
  101.  * \sa glScissor().
  102.  *
  103.  * Verifies the parameters and updates __struct gl_contextRec::Scissor. On a
  104.  * change flushes the vertices and notifies the driver via
  105.  * the dd_function_table::Scissor callback.
  106.  */
  107. void
  108. _mesa_set_scissor(struct gl_context *ctx, unsigned idx,
  109.                   GLint x, GLint y, GLsizei width, GLsizei height)
  110. {
  111.    set_scissor_no_notify(ctx, idx, x, y, width, height);
  112.  
  113.    if (ctx->Driver.Scissor)
  114.       ctx->Driver.Scissor(ctx);
  115. }
  116.  
  117. /**
  118.  * Define count scissor boxes starting at index.
  119.  *
  120.  * \param index  index of first scissor records to set
  121.  * \param count  number of scissor records to set
  122.  * \param x, y   pointer to array of struct gl_scissor_rects
  123.  *
  124.  * \sa glScissorArrayv().
  125.  *
  126.  * Verifies the parameters and call set_scissor_no_notify to do the work.
  127.  */
  128. void GLAPIENTRY
  129. _mesa_ScissorArrayv(GLuint first, GLsizei count, const GLint *v)
  130. {
  131.    int i;
  132.    struct gl_scissor_rect *p = (struct gl_scissor_rect *) v;
  133.    GET_CURRENT_CONTEXT(ctx);
  134.  
  135.    if ((first + count) > ctx->Const.MaxViewports) {
  136.       _mesa_error(ctx, GL_INVALID_VALUE,
  137.                   "glScissorArrayv: first (%d) + count (%d) >= MaxViewports (%d)",
  138.                   first, count, ctx->Const.MaxViewports);
  139.       return;
  140.    }
  141.  
  142.    /* Verify width & height */
  143.    for (i = 0; i < count; i++) {
  144.       if (p[i].Width < 0 || p[i].Height < 0) {
  145.          _mesa_error(ctx, GL_INVALID_VALUE,
  146.                      "glScissorArrayv: index (%d) width or height < 0 (%d, %d)",
  147.                      i, p[i].Width, p[i].Height);
  148.          return;
  149.       }
  150.    }
  151.  
  152.    for (i = 0; i < count; i++)
  153.       set_scissor_no_notify(ctx, i + first,
  154.                             p[i].X, p[i].Y, p[i].Width, p[i].Height);
  155.  
  156.    if (ctx->Driver.Scissor)
  157.       ctx->Driver.Scissor(ctx);
  158. }
  159.  
  160. /**
  161.  * Define the scissor box.
  162.  *
  163.  * \param index  index of scissor records to set
  164.  * \param x, y   coordinates of the scissor box lower-left corner.
  165.  * \param width  width of the scissor box.
  166.  * \param height height of the scissor box.
  167.  *
  168.  * Verifies the parameters call set_scissor_no_notify to do the work.
  169.  */
  170. static void
  171. ScissorIndexed(GLuint index, GLint left, GLint bottom,
  172.                GLsizei width, GLsizei height, const char *function)
  173. {
  174.    GET_CURRENT_CONTEXT(ctx);
  175.  
  176.    if (MESA_VERBOSE & VERBOSE_API)
  177.       _mesa_debug(ctx, "%s(%d, %d, %d, %d, %d)\n",
  178.                   function, index, left, bottom, width, height);
  179.  
  180.    if (index >= ctx->Const.MaxViewports) {
  181.       _mesa_error(ctx, GL_INVALID_VALUE,
  182.                   "%s: index (%d) >= MaxViewports (%d)",
  183.                   function, index, ctx->Const.MaxViewports);
  184.       return;
  185.    }
  186.  
  187.    if (width < 0 || height < 0) {
  188.       _mesa_error(ctx, GL_INVALID_VALUE,
  189.                   "%s: index (%d) width or height < 0 (%d, %d)",
  190.                   function, index, width, height);
  191.       return;
  192.    }
  193.  
  194.    set_scissor_no_notify(ctx, index, left, bottom, width, height);
  195.  
  196.    if (ctx->Driver.Scissor)
  197.       ctx->Driver.Scissor(ctx);
  198. }
  199.  
  200. void GLAPIENTRY
  201. _mesa_ScissorIndexed(GLuint index, GLint left, GLint bottom,
  202.                      GLsizei width, GLsizei height)
  203. {
  204.    ScissorIndexed(index, left, bottom, width, height, "glScissorIndexed");
  205. }
  206.  
  207. void GLAPIENTRY
  208. _mesa_ScissorIndexedv(GLuint index, const GLint *v)
  209. {
  210.    ScissorIndexed(index, v[0], v[1], v[2], v[3], "glScissorIndexedv");
  211. }
  212.  
  213. /**
  214.  * Initialize the context's scissor state.
  215.  * \param ctx  the GL context.
  216.  */
  217. void
  218. _mesa_init_scissor(struct gl_context *ctx)
  219. {
  220.    unsigned i;
  221.  
  222.    /* Scissor group */
  223.    ctx->Scissor.EnableFlags = 0;
  224.  
  225.    /* Note: ctx->Const.MaxViewports may not have been set by the driver yet,
  226.     * so just initialize all of them.
  227.     */
  228.    for (i = 0; i < MAX_VIEWPORTS; i++)
  229.       set_scissor_no_notify(ctx, i, 0, 0, 0, 0);
  230. }
  231.