Subversion Repositories Kolibri OS

Rev

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

  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. #include "main/glheader.h"
  26. #include "main/colormac.h"
  27. #include "main/condrender.h"
  28. #include "main/macros.h"
  29. #include "main/imports.h"
  30. #include "main/mtypes.h"
  31.  
  32. #include "s_accum.h"
  33. #include "s_context.h"
  34. #include "s_depth.h"
  35. #include "s_masking.h"
  36. #include "s_stencil.h"
  37.  
  38.  
  39. /**
  40.  * Clear the color buffer when glColorMask is in effect.
  41.  */
  42. static void
  43. clear_rgba_buffer_with_masking(struct gl_context *ctx, struct gl_renderbuffer *rb,
  44.                                GLuint buf)
  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.    SWspan span;
  51.    GLint i;
  52.  
  53.    ASSERT(rb->PutRow);
  54.  
  55.    /* Initialize color span with clear color */
  56.    /* XXX optimize for clearcolor == black/zero (bzero) */
  57.    INIT_SPAN(span, GL_BITMAP);
  58.    span.end = width;
  59.    span.arrayMask = SPAN_RGBA;
  60.    span.array->ChanType = rb->DataType;
  61.    if (span.array->ChanType == GL_UNSIGNED_BYTE) {
  62.       GLubyte clearColor[4];
  63.       UNCLAMPED_FLOAT_TO_UBYTE(clearColor[RCOMP], ctx->Color.ClearColor[0]);
  64.       UNCLAMPED_FLOAT_TO_UBYTE(clearColor[GCOMP], ctx->Color.ClearColor[1]);
  65.       UNCLAMPED_FLOAT_TO_UBYTE(clearColor[BCOMP], ctx->Color.ClearColor[2]);
  66.       UNCLAMPED_FLOAT_TO_UBYTE(clearColor[ACOMP], ctx->Color.ClearColor[3]);
  67.       for (i = 0; i < width; i++) {
  68.          COPY_4UBV(span.array->rgba[i], clearColor);
  69.       }
  70.    }
  71.    else if (span.array->ChanType == GL_UNSIGNED_SHORT) {
  72.       GLushort clearColor[4];
  73.       UNCLAMPED_FLOAT_TO_USHORT(clearColor[RCOMP], ctx->Color.ClearColor[0]);
  74.       UNCLAMPED_FLOAT_TO_USHORT(clearColor[GCOMP], ctx->Color.ClearColor[1]);
  75.       UNCLAMPED_FLOAT_TO_USHORT(clearColor[BCOMP], ctx->Color.ClearColor[2]);
  76.       UNCLAMPED_FLOAT_TO_USHORT(clearColor[ACOMP], ctx->Color.ClearColor[3]);
  77.       for (i = 0; i < width; i++) {
  78.          COPY_4V_CAST(span.array->rgba[i], clearColor, GLchan);
  79.       }
  80.    }
  81.    else {
  82.       ASSERT(span.array->ChanType == GL_FLOAT);
  83.       for (i = 0; i < width; i++) {
  84.          CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][0], ctx->Color.ClearColor[0]);
  85.          CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][1], ctx->Color.ClearColor[1]);
  86.          CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][2], ctx->Color.ClearColor[2]);
  87.          CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][3], ctx->Color.ClearColor[3]);
  88.       }
  89.    }
  90.  
  91.    /* Note that masking will change the color values, but only the
  92.     * channels for which the write mask is GL_FALSE.  The channels
  93.     * which which are write-enabled won't get modified.
  94.     */
  95.    for (i = 0; i < height; i++) {
  96.       span.x = x;
  97.       span.y = y + i;
  98.       _swrast_mask_rgba_span(ctx, rb, &span, buf);
  99.       /* write masked row */
  100.       rb->PutRow(ctx, rb, width, x, y + i, span.array->rgba, NULL);
  101.    }
  102. }
  103.  
  104.  
  105. /**
  106.  * Clear an rgba color buffer without channel masking.
  107.  */
  108. static void
  109. clear_rgba_buffer(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint buf)
  110. {
  111.    const GLint x = ctx->DrawBuffer->_Xmin;
  112.    const GLint y = ctx->DrawBuffer->_Ymin;
  113.    const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
  114.    const GLint width  = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
  115.    GLubyte clear8[4];
  116.    GLushort clear16[4];
  117.    GLvoid *clearVal;
  118.    GLint i;
  119.  
  120.    ASSERT(ctx->Color.ColorMask[buf][0] &&
  121.           ctx->Color.ColorMask[buf][1] &&
  122.           ctx->Color.ColorMask[buf][2] &&
  123.           ctx->Color.ColorMask[buf][3]);            
  124.  
  125.    ASSERT(rb->PutMonoRow);
  126.  
  127.    switch (rb->DataType) {
  128.       case GL_UNSIGNED_BYTE:
  129.          UNCLAMPED_FLOAT_TO_UBYTE(clear8[0], ctx->Color.ClearColor[0]);
  130.          UNCLAMPED_FLOAT_TO_UBYTE(clear8[1], ctx->Color.ClearColor[1]);
  131.          UNCLAMPED_FLOAT_TO_UBYTE(clear8[2], ctx->Color.ClearColor[2]);
  132.          UNCLAMPED_FLOAT_TO_UBYTE(clear8[3], ctx->Color.ClearColor[3]);
  133.          clearVal = clear8;
  134.          break;
  135.       case GL_UNSIGNED_SHORT:
  136.          UNCLAMPED_FLOAT_TO_USHORT(clear16[0], ctx->Color.ClearColor[0]);
  137.          UNCLAMPED_FLOAT_TO_USHORT(clear16[1], ctx->Color.ClearColor[1]);
  138.          UNCLAMPED_FLOAT_TO_USHORT(clear16[2], ctx->Color.ClearColor[2]);
  139.          UNCLAMPED_FLOAT_TO_USHORT(clear16[3], ctx->Color.ClearColor[3]);
  140.          clearVal = clear16;
  141.          break;
  142.       case GL_FLOAT:
  143.          clearVal = ctx->Color.ClearColor;
  144.          break;
  145.       default:
  146.          _mesa_problem(ctx, "Bad rb DataType in clear_color_buffer");
  147.          return;
  148.    }
  149.  
  150.    for (i = 0; i < height; i++) {
  151.       rb->PutMonoRow(ctx, rb, width, x, y + i, clearVal, NULL);
  152.    }
  153. }
  154.  
  155.  
  156. /**
  157.  * Clear the front/back/left/right/aux color buffers.
  158.  * This function is usually only called if the device driver can't
  159.  * clear its own color buffers for some reason (such as with masking).
  160.  */
  161. static void
  162. clear_color_buffers(struct gl_context *ctx)
  163. {
  164.    GLuint buf;
  165.  
  166.    for (buf = 0; buf < ctx->DrawBuffer->_NumColorDrawBuffers; buf++) {
  167.       struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[buf];
  168.       if (ctx->Color.ColorMask[buf][0] == 0 ||
  169.           ctx->Color.ColorMask[buf][1] == 0 ||
  170.           ctx->Color.ColorMask[buf][2] == 0 ||
  171.           ctx->Color.ColorMask[buf][3] == 0) {
  172.          clear_rgba_buffer_with_masking(ctx, rb, buf);
  173.       }
  174.       else {
  175.          clear_rgba_buffer(ctx, rb, buf);
  176.       }
  177.    }
  178. }
  179.  
  180.  
  181. /**
  182.  * Called via the device driver's ctx->Driver.Clear() function if the
  183.  * device driver can't clear one or more of the buffers itself.
  184.  * \param buffers  bitfield of BUFFER_BIT_* values indicating which
  185.  *                 renderbuffers are to be cleared.
  186.  * \param all  if GL_TRUE, clear whole buffer, else clear specified region.
  187.  */
  188. void
  189. _swrast_Clear(struct gl_context *ctx, GLbitfield buffers)
  190. {
  191. #ifdef DEBUG_FOO
  192.    {
  193.       const GLbitfield legalBits =
  194.          BUFFER_BIT_FRONT_LEFT |
  195.          BUFFER_BIT_FRONT_RIGHT |
  196.          BUFFER_BIT_BACK_LEFT |
  197.          BUFFER_BIT_BACK_RIGHT |
  198.          BUFFER_BIT_DEPTH |
  199.          BUFFER_BIT_STENCIL |
  200.          BUFFER_BIT_ACCUM |
  201.          BUFFER_BIT_AUX0;
  202.       assert((buffers & (~legalBits)) == 0);
  203.    }
  204. #endif
  205.  
  206.    if (!_mesa_check_conditional_render(ctx))
  207.       return; /* don't clear */
  208.  
  209.    swrast_render_start(ctx);
  210.  
  211.    /* do software clearing here */
  212.    if (buffers) {
  213.       if ((buffers & BUFFER_BITS_COLOR)
  214.           && (ctx->DrawBuffer->_NumColorDrawBuffers > 0)) {
  215.          clear_color_buffers(ctx);
  216.       }
  217.       if (buffers & BUFFER_BIT_DEPTH) {
  218.          _swrast_clear_depth_buffer(ctx, ctx->DrawBuffer->_DepthBuffer);
  219.       }
  220.       if (buffers & BUFFER_BIT_ACCUM) {
  221.          _swrast_clear_accum_buffer(ctx,
  222.                        ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);
  223.       }
  224.       if (buffers & BUFFER_BIT_STENCIL) {
  225.          _swrast_clear_stencil_buffer(ctx, ctx->DrawBuffer->_StencilBuffer);
  226.       }
  227.    }
  228.  
  229.    swrast_render_finish(ctx);
  230. }
  231.