1e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library
3a429a25cd55b8c16356a60452de92228bb6c71b0Brian * Version:  7.1
422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
5a429a25cd55b8c16356a60452de92228bb6c71b0Brian * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
7e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
8e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * copy of this software and associated documentation files (the "Software"),
9e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * to deal in the Software without restriction, including without limitation
10e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * and/or sell copies of the Software, and to permit persons to whom the
12e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Software is furnished to do so, subject to the following conditions:
1322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
14e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The above copyright notice and this permission notice shall be included
15e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * in all copies or substantial portions of the Software.
1622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
17e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
24e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
2509700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul/**
2609700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul * \file swrast/s_bitmap.c
2709700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul * \brief glBitmap rendering.
2809700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul * \author Brian Paul
2909700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul */
30e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
31bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/glheader.h"
32bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/bufferobj.h"
33ab26682eb4db0dbe160b13f1e320ec9164c3afc5Brian Paul#include "main/condrender.h"
34bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/image.h"
35bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/macros.h"
36b70610b9823fc7dc3672735c11be1a75fbb1a2a4Brian Paul#include "main/pbo.h"
37e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
38cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "s_context.h"
39733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul#include "s_span.h"
40e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
41e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
42e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
439b507639ab31b2d611344f061614e71d47c9a84cBrian Paul/**
44e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Render a bitmap.
459b507639ab31b2d611344f061614e71d47c9a84cBrian Paul * Called via ctx->Driver.Bitmap()
469b507639ab31b2d611344f061614e71d47c9a84cBrian Paul * All parameter error checking will have been done before this is called.
47e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
4822144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughesvoid
49f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_Bitmap( struct gl_context *ctx, GLint px, GLint py,
50e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell		GLsizei width, GLsizei height,
51e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell		const struct gl_pixelstore_attrib *unpack,
52e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell		const GLubyte *bitmap )
53e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
54e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLint row, col;
55733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   GLuint count = 0;
56cdb27e8242215271364602995d85607cfc06d441Brian Paul   SWspan span;
57e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
58e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ASSERT(ctx->RenderMode == GL_RENDER);
597a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
60ab26682eb4db0dbe160b13f1e320ec9164c3afc5Brian Paul   if (!_mesa_check_conditional_render(ctx))
61ab26682eb4db0dbe160b13f1e320ec9164c3afc5Brian Paul      return; /* don't draw */
62ab26682eb4db0dbe160b13f1e320ec9164c3afc5Brian Paul
631b448c7a5cafa68eeead2a4c45f4362a9883383bBrian Paul   bitmap = (const GLubyte *) _mesa_map_pbo_source(ctx, unpack, bitmap);
64d933be6baf98624c609d422a9b083a08f67e8bdbBrian   if (!bitmap)
65d933be6baf98624c609d422a9b083a08f67e8bdbBrian      return;
66e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
672d5b86be25a7ccb729e746aa5e1bdd537d76df68Brian Paul   swrast_render_start(ctx);
68709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell
69cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell   if (SWRAST_CONTEXT(ctx)->NewState)
70cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      _swrast_validate_derived( ctx );
71cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell
72f4b103dc993491355ec3e3640d9cb060138175c2Brian   INIT_SPAN(span, GL_BITMAP);
73f4b103dc993491355ec3e3640d9cb060138175c2Brian   span.end = width;
74f4b103dc993491355ec3e3640d9cb060138175c2Brian   span.arrayMask = SPAN_XY;
759e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   _swrast_span_default_attribs(ctx, &span);
7622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes
773bde211549b3a819c33793fb87f80121d0f028f2Brian Paul   for (row = 0; row < height; row++) {
7860909388ab136d849d99eab49e782a53772a618fBrian Paul      const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
7960909388ab136d849d99eab49e782a53772a618fBrian Paul                 bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
80e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
81e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (unpack->LsbFirst) {
82e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Lsb first */
83e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
84733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         for (col = 0; col < width; col++) {
85e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            if (*src & mask) {
8677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul               span.array->x[count] = px + col;
8777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul               span.array->y[count] = py + row;
88733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul               count++;
89e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            }
90e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            if (mask == 128U) {
91e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               src++;
92e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               mask = 1U;
93e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            }
94e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            else {
95e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               mask = mask << 1;
96e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            }
97e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
98e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
99e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* get ready for next row */
100e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (mask != 1)
101e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            src++;
102e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
103e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
104e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Msb first */
105e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
106733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         for (col = 0; col < width; col++) {
107e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            if (*src & mask) {
10877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul               span.array->x[count] = px + col;
10977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul               span.array->y[count] = py + row;
110733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul               count++;
111e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            }
112e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            if (mask == 1U) {
113e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               src++;
114e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               mask = 128U;
115e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            }
116e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            else {
117e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               mask = mask >> 1;
118e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            }
119e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
120e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
121e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* get ready for next row */
122e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (mask != 128)
123e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            src++;
124e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
125e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
12647d88ef204b42a9220c6be3e98c92df9c9aa0860Brian Paul      if (count + width >= SWRAST_MAX_WIDTH || row + 1 == height) {
127733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         /* flush the span */
12877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         span.end = count;
129d05badba291ce4444b6aaabfd577bdbcf7929193Ian Romanick         _swrast_write_rgba_span(ctx, &span);
13077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         span.end = 0;
131733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         count = 0;
132733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      }
133733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   }
134709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell
1352d5b86be25a7ccb729e746aa5e1bdd537d76df68Brian Paul   swrast_render_finish(ctx);
136355467bed8cf34cf5967c7be3c5f1b87ff08f845Brian Paul
1371b448c7a5cafa68eeead2a4c45f4362a9883383bBrian Paul   _mesa_unmap_pbo_source(ctx, unpack);
138e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
13909700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul
14009700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul
14109700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul#if 0
14209700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul/*
14309700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul * XXX this is another way to implement Bitmap.  Use horizontal runs of
1449b507639ab31b2d611344f061614e71d47c9a84cBrian Paul * fragments, initializing the mask array to indicate which fragments to
14509700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul * draw or skip.
14609700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul */
14709700ee358cd07634161ac7802e97ddbe6c075bfBrian Paulvoid
148f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_Bitmap( struct gl_context *ctx, GLint px, GLint py,
14909700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul		GLsizei width, GLsizei height,
15009700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul		const struct gl_pixelstore_attrib *unpack,
15109700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul		const GLubyte *bitmap )
15209700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul{
15309700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul   SWcontext *swrast = SWRAST_CONTEXT(ctx);
15409700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul   GLint row, col;
155cdb27e8242215271364602995d85607cfc06d441Brian Paul   SWspan span;
15609700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul
15709700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul   ASSERT(ctx->RenderMode == GL_RENDER);
15809700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul   ASSERT(bitmap);
15909700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul
1602d5b86be25a7ccb729e746aa5e1bdd537d76df68Brian Paul   swrast_render_start(ctx);
16109700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul
16209700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul   if (SWRAST_CONTEXT(ctx)->NewState)
16309700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul      _swrast_validate_derived( ctx );
16409700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul
165f4b103dc993491355ec3e3640d9cb060138175c2Brian   INIT_SPAN(span, GL_BITMAP);
166f4b103dc993491355ec3e3640d9cb060138175c2Brian   span.end = width;
167f4b103dc993491355ec3e3640d9cb060138175c2Brian   span.arrayMask = SPAN_MASK;
1689e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   _swrast_span_default_attribs(ctx, &span);
16977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul
17077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   /*span.arrayMask |= SPAN_MASK;*/  /* we'll init span.mask[] */
17177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   span.x = px;
17277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   span.y = py;
17377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   /*span.end = width;*/
17409700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul
17577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   for (row=0; row<height; row++, span.y++) {
17660909388ab136d849d99eab49e782a53772a618fBrian Paul      const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
17760909388ab136d849d99eab49e782a53772a618fBrian Paul                 bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
17809700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul
17909700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul      if (unpack->LsbFirst) {
18009700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul         /* Lsb first */
18109700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul         GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
18209700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul         for (col=0; col<width; col++) {
18377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            span.array->mask[col] = (*src & mask) ? GL_TRUE : GL_FALSE;
18409700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul            if (mask == 128U) {
18509700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul               src++;
18609700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul               mask = 1U;
18709700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul            }
18809700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul            else {
18909700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul               mask = mask << 1;
19009700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul            }
19109700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul         }
19209700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul
193d05badba291ce4444b6aaabfd577bdbcf7929193Ian Romanick         _swrast_write_rgba_span(ctx, &span);
19409700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul
19509700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul         /* get ready for next row */
19609700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul         if (mask != 1)
19709700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul            src++;
19809700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul      }
19909700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul      else {
20009700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul         /* Msb first */
20109700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul         GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
20209700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul         for (col=0; col<width; col++) {
20377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            span.array->mask[col] = (*src & mask) ? GL_TRUE : GL_FALSE;
20409700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul            if (mask == 1U) {
20509700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul               src++;
20609700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul               mask = 128U;
20709700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul            }
20809700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul            else {
20909700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul               mask = mask >> 1;
21009700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul            }
21109700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul         }
21209700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul
213d05badba291ce4444b6aaabfd577bdbcf7929193Ian Romanick         _swrast_write_rgba_span(ctx, &span);
21409700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul
21509700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul         /* get ready for next row */
21609700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul         if (mask != 128)
21709700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul            src++;
21809700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul      }
21909700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul   }
22009700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul
2212d5b86be25a7ccb729e746aa5e1bdd537d76df68Brian Paul   swrast_render_finish(ctx);
22209700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul}
22309700ee358cd07634161ac7802e97ddbe6c075bfBrian Paul#endif
224