Home | History | Annotate | Download | only in swrast
      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 swrast/s_bitmap.c
     27  * \brief glBitmap rendering.
     28  * \author Brian Paul
     29  */
     30 
     31 #include "main/glheader.h"
     32 #include "main/bufferobj.h"
     33 #include "main/condrender.h"
     34 #include "main/image.h"
     35 #include "main/macros.h"
     36 #include "main/pbo.h"
     37 
     38 #include "s_context.h"
     39 #include "s_span.h"
     40 
     41 
     42 
     43 /**
     44  * Render a bitmap.
     45  * Called via ctx->Driver.Bitmap()
     46  * All parameter error checking will have been done before this is called.
     47  */
     48 void
     49 _swrast_Bitmap( struct gl_context *ctx, GLint px, GLint py,
     50 		GLsizei width, GLsizei height,
     51 		const struct gl_pixelstore_attrib *unpack,
     52 		const GLubyte *bitmap )
     53 {
     54    GLint row, col;
     55    GLuint count = 0;
     56    SWspan span;
     57 
     58    ASSERT(ctx->RenderMode == GL_RENDER);
     59 
     60    if (!_mesa_check_conditional_render(ctx))
     61       return; /* don't draw */
     62 
     63    bitmap = (const GLubyte *) _mesa_map_pbo_source(ctx, unpack, bitmap);
     64    if (!bitmap)
     65       return;
     66 
     67    swrast_render_start(ctx);
     68 
     69    if (SWRAST_CONTEXT(ctx)->NewState)
     70       _swrast_validate_derived( ctx );
     71 
     72    INIT_SPAN(span, GL_BITMAP);
     73    span.end = width;
     74    span.arrayMask = SPAN_XY;
     75    _swrast_span_default_attribs(ctx, &span);
     76 
     77    for (row = 0; row < height; row++) {
     78       const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
     79                  bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
     80 
     81       if (unpack->LsbFirst) {
     82          /* Lsb first */
     83          GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
     84          for (col = 0; col < width; col++) {
     85             if (*src & mask) {
     86                span.array->x[count] = px + col;
     87                span.array->y[count] = py + row;
     88                count++;
     89             }
     90             if (mask == 128U) {
     91                src++;
     92                mask = 1U;
     93             }
     94             else {
     95                mask = mask << 1;
     96             }
     97          }
     98 
     99          /* get ready for next row */
    100          if (mask != 1)
    101             src++;
    102       }
    103       else {
    104          /* Msb first */
    105          GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
    106          for (col = 0; col < width; col++) {
    107             if (*src & mask) {
    108                span.array->x[count] = px + col;
    109                span.array->y[count] = py + row;
    110                count++;
    111             }
    112             if (mask == 1U) {
    113                src++;
    114                mask = 128U;
    115             }
    116             else {
    117                mask = mask >> 1;
    118             }
    119          }
    120 
    121          /* get ready for next row */
    122          if (mask != 128)
    123             src++;
    124       }
    125 
    126       if (count + width >= SWRAST_MAX_WIDTH || row + 1 == height) {
    127          /* flush the span */
    128          span.end = count;
    129          _swrast_write_rgba_span(ctx, &span);
    130          span.end = 0;
    131          count = 0;
    132       }
    133    }
    134 
    135    swrast_render_finish(ctx);
    136 
    137    _mesa_unmap_pbo_source(ctx, unpack);
    138 }
    139 
    140 
    141 #if 0
    142 /*
    143  * XXX this is another way to implement Bitmap.  Use horizontal runs of
    144  * fragments, initializing the mask array to indicate which fragments to
    145  * draw or skip.
    146  */
    147 void
    148 _swrast_Bitmap( struct gl_context *ctx, GLint px, GLint py,
    149 		GLsizei width, GLsizei height,
    150 		const struct gl_pixelstore_attrib *unpack,
    151 		const GLubyte *bitmap )
    152 {
    153    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    154    GLint row, col;
    155    SWspan span;
    156 
    157    ASSERT(ctx->RenderMode == GL_RENDER);
    158    ASSERT(bitmap);
    159 
    160    swrast_render_start(ctx);
    161 
    162    if (SWRAST_CONTEXT(ctx)->NewState)
    163       _swrast_validate_derived( ctx );
    164 
    165    INIT_SPAN(span, GL_BITMAP);
    166    span.end = width;
    167    span.arrayMask = SPAN_MASK;
    168    _swrast_span_default_attribs(ctx, &span);
    169 
    170    /*span.arrayMask |= SPAN_MASK;*/  /* we'll init span.mask[] */
    171    span.x = px;
    172    span.y = py;
    173    /*span.end = width;*/
    174 
    175    for (row=0; row<height; row++, span.y++) {
    176       const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
    177                  bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
    178 
    179       if (unpack->LsbFirst) {
    180          /* Lsb first */
    181          GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
    182          for (col=0; col<width; col++) {
    183             span.array->mask[col] = (*src & mask) ? GL_TRUE : GL_FALSE;
    184             if (mask == 128U) {
    185                src++;
    186                mask = 1U;
    187             }
    188             else {
    189                mask = mask << 1;
    190             }
    191          }
    192 
    193          _swrast_write_rgba_span(ctx, &span);
    194 
    195          /* get ready for next row */
    196          if (mask != 1)
    197             src++;
    198       }
    199       else {
    200          /* Msb first */
    201          GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
    202          for (col=0; col<width; col++) {
    203             span.array->mask[col] = (*src & mask) ? GL_TRUE : GL_FALSE;
    204             if (mask == 1U) {
    205                src++;
    206                mask = 128U;
    207             }
    208             else {
    209                mask = mask >> 1;
    210             }
    211          }
    212 
    213          _swrast_write_rgba_span(ctx, &span);
    214 
    215          /* get ready for next row */
    216          if (mask != 128)
    217             src++;
    218       }
    219    }
    220 
    221    swrast_render_finish(ctx);
    222 }
    223 #endif
    224