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. #include "main/glheader.h"
  26. #include "main/accum.h"
  27. #include "main/condrender.h"
  28. #include "main/format_pack.h"
  29. #include "main/macros.h"
  30. #include "main/imports.h"
  31. #include "main/mtypes.h"
  32.  
  33. #include "s_context.h"
  34. #include "s_depth.h"
  35. #include "s_stencil.h"
  36.  
  37.  
  38.  
  39. /**
  40.  * Clear an rgba color buffer with masking if needed.
  41.  */
  42. static void
  43. clear_rgba_buffer(struct gl_context *ctx, struct gl_renderbuffer *rb,
  44.                   const GLubyte colorMask[4])
  45. {
  46.    const GLint x = ctx->DrawBuffer->_Xmin;
  47.    const GLint y = ctx->DrawBuffer->_Ymin;
  48.    const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
  49.    const GLint width  = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
  50.    const GLuint pixelSize = _mesa_get_format_bytes(rb->Format);
  51.    const GLboolean doMasking = (colorMask[0] == 0 ||
  52.                                 colorMask[1] == 0 ||
  53.                                 colorMask[2] == 0 ||
  54.                                 colorMask[3] == 0);
  55.    const GLfloat (*clearColor)[4] =
  56.       (const GLfloat (*)[4]) ctx->Color.ClearColor.f;
  57.    GLbitfield mapMode = GL_MAP_WRITE_BIT;
  58.    GLubyte *map;
  59.    GLint rowStride;
  60.    GLint i, j;
  61.  
  62.    if (doMasking) {
  63.       /* we'll need to read buffer values too */
  64.       mapMode |= GL_MAP_READ_BIT;
  65.    }
  66.  
  67.    /* map dest buffer */
  68.    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
  69.                                mapMode, &map, &rowStride);
  70.    if (!map) {
  71.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(color)");
  72.       return;
  73.    }
  74.  
  75.    /* for 1, 2, 4-byte clearing */
  76. #define SIMPLE_TYPE_CLEAR(TYPE)                                         \
  77.    do {                                                                 \
  78.       TYPE pixel, pixelMask;                                            \
  79.       _mesa_pack_float_rgba_row(rb->Format, 1, clearColor, &pixel);     \
  80.       if (doMasking) {                                                  \
  81.          _mesa_pack_colormask(rb->Format, colorMask, &pixelMask);       \
  82.          pixel &= pixelMask;                                            \
  83.          pixelMask = ~pixelMask;                                        \
  84.       }                                                                 \
  85.       for (i = 0; i < height; i++) {                                    \
  86.          TYPE *row = (TYPE *) map;                                      \
  87.          if (doMasking) {                                               \
  88.             for (j = 0; j < width; j++) {                               \
  89.                row[j] = (row[j] & pixelMask) | pixel;                   \
  90.             }                                                           \
  91.          }                                                              \
  92.          else {                                                         \
  93.             for (j = 0; j < width; j++) {                               \
  94.                row[j] = pixel;                                          \
  95.             }                                                           \
  96.          }                                                              \
  97.          map += rowStride;                                              \
  98.       }                                                                 \
  99.    } while (0)
  100.  
  101.  
  102.    /* for 3, 6, 8, 12, 16-byte clearing */
  103. #define MULTI_WORD_CLEAR(TYPE, N)                                       \
  104.    do {                                                                 \
  105.       TYPE pixel[N], pixelMask[N];                                      \
  106.       GLuint k;                                                         \
  107.       _mesa_pack_float_rgba_row(rb->Format, 1, clearColor, pixel);      \
  108.       if (doMasking) {                                                  \
  109.          _mesa_pack_colormask(rb->Format, colorMask, pixelMask);        \
  110.          for (k = 0; k < N; k++) {                                      \
  111.             pixel[k] &= pixelMask[k];                                   \
  112.             pixelMask[k] = ~pixelMask[k];                               \
  113.          }                                                              \
  114.       }                                                                 \
  115.       for (i = 0; i < height; i++) {                                    \
  116.          TYPE *row = (TYPE *) map;                                      \
  117.          if (doMasking) {                                               \
  118.             for (j = 0; j < width; j++) {                               \
  119.                for (k = 0; k < N; k++) {                                \
  120.                   row[j * N + k] =                                      \
  121.                      (row[j * N + k] & pixelMask[k]) | pixel[k];        \
  122.                }                                                        \
  123.             }                                                           \
  124.          }                                                              \
  125.          else {                                                         \
  126.             for (j = 0; j < width; j++) {                               \
  127.                for (k = 0; k < N; k++) {                                \
  128.                   row[j * N + k] = pixel[k];                            \
  129.                }                                                        \
  130.             }                                                           \
  131.          }                                                              \
  132.          map += rowStride;                                              \
  133.       }                                                                 \
  134.    } while(0)
  135.  
  136.    switch (pixelSize) {
  137.    case 1:
  138.       SIMPLE_TYPE_CLEAR(GLubyte);
  139.       break;
  140.    case 2:
  141.       SIMPLE_TYPE_CLEAR(GLushort);
  142.       break;
  143.    case 3:
  144.       MULTI_WORD_CLEAR(GLubyte, 3);
  145.       break;
  146.    case 4:
  147.       SIMPLE_TYPE_CLEAR(GLuint);
  148.       break;
  149.    case 6:
  150.       MULTI_WORD_CLEAR(GLushort, 3);
  151.       break;
  152.    case 8:
  153.       MULTI_WORD_CLEAR(GLuint, 2);
  154.       break;
  155.    case 12:
  156.       MULTI_WORD_CLEAR(GLuint, 3);
  157.       break;
  158.    case 16:
  159.       MULTI_WORD_CLEAR(GLuint, 4);
  160.       break;
  161.    default:
  162.       _mesa_problem(ctx, "bad pixel size in clear_rgba_buffer()");
  163.    }
  164.  
  165.    /* unmap buffer */
  166.    ctx->Driver.UnmapRenderbuffer(ctx, rb);
  167. }
  168.  
  169.  
  170. /**
  171.  * Clear the front/back/left/right/aux color buffers.
  172.  * This function is usually only called if the device driver can't
  173.  * clear its own color buffers for some reason (such as with masking).
  174.  */
  175. static void
  176. clear_color_buffers(struct gl_context *ctx)
  177. {
  178.    GLuint buf;
  179.  
  180.    for (buf = 0; buf < ctx->DrawBuffer->_NumColorDrawBuffers; buf++) {
  181.       struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[buf];
  182.  
  183.       /* If this is an ES2 context or GL_ARB_ES2_compatibility is supported,
  184.        * the framebuffer can be complete with some attachments be missing.  In
  185.        * this case the _ColorDrawBuffers pointer will be NULL.
  186.        */
  187.       if (rb == NULL)
  188.          continue;
  189.  
  190.       clear_rgba_buffer(ctx, rb, ctx->Color.ColorMask[buf]);
  191.    }
  192. }
  193.  
  194.  
  195. /**
  196.  * Called via the device driver's ctx->Driver.Clear() function if the
  197.  * device driver can't clear one or more of the buffers itself.
  198.  * \param buffers  bitfield of BUFFER_BIT_* values indicating which
  199.  *                 renderbuffers are to be cleared.
  200.  * \param all  if GL_TRUE, clear whole buffer, else clear specified region.
  201.  */
  202. void
  203. _swrast_Clear(struct gl_context *ctx, GLbitfield buffers)
  204. {
  205.    const GLbitfield BUFFER_DS = BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL;
  206.  
  207. #ifdef DEBUG_FOO
  208.    {
  209.       const GLbitfield legalBits =
  210.          BUFFER_BIT_FRONT_LEFT |
  211.          BUFFER_BIT_FRONT_RIGHT |
  212.          BUFFER_BIT_BACK_LEFT |
  213.          BUFFER_BIT_BACK_RIGHT |
  214.          BUFFER_BIT_DEPTH |
  215.          BUFFER_BIT_STENCIL |
  216.          BUFFER_BIT_ACCUM |
  217.          BUFFER_BIT_AUX0;
  218.       assert((buffers & (~legalBits)) == 0);
  219.    }
  220. #endif
  221.  
  222.    if (!_mesa_check_conditional_render(ctx))
  223.       return; /* don't clear */
  224.  
  225.    if (SWRAST_CONTEXT(ctx)->NewState)
  226.       _swrast_validate_derived(ctx);
  227.  
  228.    if ((buffers & BUFFER_BITS_COLOR)
  229.        && (ctx->DrawBuffer->_NumColorDrawBuffers > 0)) {
  230.       clear_color_buffers(ctx);
  231.    }
  232.  
  233.    if (buffers & BUFFER_BIT_ACCUM) {
  234.       _mesa_clear_accum_buffer(ctx);
  235.    }
  236.  
  237.    if (buffers & BUFFER_DS) {
  238.       struct gl_renderbuffer *depthRb =
  239.          ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
  240.       struct gl_renderbuffer *stencilRb =
  241.          ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
  242.  
  243.       if ((buffers & BUFFER_DS) == BUFFER_DS && depthRb == stencilRb) {
  244.          /* clear depth and stencil together */
  245.          _swrast_clear_depth_stencil_buffer(ctx);
  246.       }
  247.       else {
  248.          /* clear depth, stencil separately */
  249.          if (buffers & BUFFER_BIT_DEPTH) {
  250.             _swrast_clear_depth_buffer(ctx);
  251.          }
  252.          if (buffers & BUFFER_BIT_STENCIL) {
  253.             _swrast_clear_stencil_buffer(ctx);
  254.          }
  255.       }
  256.    }
  257. }
  258.