st_cb_bitmap.c File Reference

Include dependency graph for st_cb_bitmap.c:

Go to the source code of this file.

Data Structures

struct  bitmap_cache

Defines

#define BITMAP_CACHE_WIDTH   512
#define BITMAP_CACHE_HEIGHT   32
#define SET_PIXEL(COL, ROW)   destBuffer[(py + (ROW)) * destStride + px + (COL)] = 0x0;

Functions

static struct st_fragment_programmake_bitmap_fragment_program (GLcontext *ctx, GLuint samplerIndex)
 Make fragment program for glBitmap: Sample the texture and kill the fragment if the bit is 0.
static int find_free_bit (uint bitfield)
static struct st_fragment_programcombined_bitmap_fragment_program (GLcontext *ctx)
 Combine basic bitmap fragment program with the user-defined program.
static void unpack_bitmap (struct st_context *st, GLint px, GLint py, GLsizei width, GLsizei height, const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap, ubyte *destBuffer, uint destStride)
 Copy user-provide bitmap bits into texture buffer, expanding bits into texels.
static struct pipe_texturemake_bitmap_texture (GLcontext *ctx, GLsizei width, GLsizei height, const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap)
 Create a texture which represents a bitmap image.
static GLuint setup_bitmap_vertex_data (struct st_context *st, int x, int y, int width, int height, float z, const float color[4])
static void draw_bitmap_quad (GLcontext *ctx, GLint x, GLint y, GLfloat z, GLsizei width, GLsizei height, struct pipe_texture *pt, const GLfloat *color)
 Render a glBitmap by drawing a textured quad.
static void reset_cache (struct st_context *st)
void st_flush_bitmap_cache (struct st_context *st)
 If there's anything in the bitmap cache, draw/flush it now.
void st_flush_bitmap (struct st_context *st)
static GLboolean accum_bitmap (struct st_context *st, GLint x, GLint y, GLsizei width, GLsizei height, const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap)
 Try to accumulate this glBitmap call in the bitmap cache.
static void st_Bitmap (GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap)
 Called via ctx->Driver.Bitmap().
void st_init_bitmap_functions (struct dd_function_table *functions)
 Per-context init.
void st_init_bitmap (struct st_context *st)
 Per-context init.
void st_destroy_bitmap (struct st_context *st)
 Per-context tear-down.

Variables

static GLboolean UseBitmapCache = GL_TRUE
 glBitmaps are drawn as textured quads.


Define Documentation

#define BITMAP_CACHE_HEIGHT   32

Definition at line 84 of file st_cb_bitmap.c.

#define BITMAP_CACHE_WIDTH   512

Definition at line 83 of file st_cb_bitmap.c.

#define SET_PIXEL ( COL,
ROW   )     destBuffer[(py + (ROW)) * destStride + px + (COL)] = 0x0;


Function Documentation

static GLboolean accum_bitmap ( struct st_context st,
GLint  x,
GLint  y,
GLsizei  width,
GLsizei  height,
const struct gl_pixelstore_attrib *  unpack,
const GLubyte *  bitmap 
) [static]

Try to accumulate this glBitmap call in the bitmap cache.

Returns:
GL_TRUE for success, GL_FALSE if bitmap is too large, etc.

Definition at line 662 of file st_cb_bitmap.c.

References assert, st_context::bitmap, BITMAP_CACHE_HEIGHT, BITMAP_CACHE_WIDTH, bitmap_cache::buffer, st_context::cache, bitmap_cache::color, COPY_4FV, st_context::ctx, bitmap_cache::empty, st_flush_bitmap_cache(), unpack_bitmap(), bitmap_cache::xmax, bitmap_cache::xmin, bitmap_cache::xpos, bitmap_cache::ymax, bitmap_cache::ymin, and bitmap_cache::ypos.

00666 {
00667    struct bitmap_cache *cache = st->bitmap.cache;
00668    int px = -999, py;
00669 
00670    if (width > BITMAP_CACHE_WIDTH ||
00671        height > BITMAP_CACHE_HEIGHT)
00672       return GL_FALSE; /* too big to cache */
00673 
00674    if (!cache->empty) {
00675       px = x - cache->xpos;  /* pos in buffer */
00676       py = y - cache->ypos;
00677       if (px < 0 || px + width > BITMAP_CACHE_WIDTH ||
00678           py < 0 || py + height > BITMAP_CACHE_HEIGHT ||
00679           !TEST_EQ_4V(st->ctx->Current.RasterColor, cache->color)) {
00680          /* This bitmap would extend beyond cache bounds, or the bitmap
00681           * color is changing
00682           * so flush and continue.
00683           */
00684          st_flush_bitmap_cache(st);
00685       }
00686    }
00687 
00688    if (cache->empty) {
00689       /* Initialize.  Center bitmap vertically in the buffer. */
00690       px = 0;
00691       py = (BITMAP_CACHE_HEIGHT - height) / 2;
00692       cache->xpos = x;
00693       cache->ypos = y - py;
00694       cache->empty = GL_FALSE;
00695       COPY_4FV(cache->color, st->ctx->Current.RasterColor);
00696    }
00697 
00698    assert(px != -999);
00699 
00700    if (x < cache->xmin)
00701       cache->xmin = x;
00702    if (y < cache->ymin)
00703       cache->ymin = y;
00704    if (x + width > cache->xmax)
00705       cache->xmax = x + width;
00706    if (y + height > cache->ymax)
00707       cache->ymax = y + height;
00708 
00709    unpack_bitmap(st, px, py, width, height, unpack, bitmap,
00710                  cache->buffer, BITMAP_CACHE_WIDTH);
00711 
00712    return GL_TRUE; /* accumulated */
00713 }

static struct st_fragment_program* combined_bitmap_fragment_program ( GLcontext *  ctx  )  [static, read]

Combine basic bitmap fragment program with the user-defined program.

Definition at line 183 of file st_cb_bitmap.c.

References st_fragment_program::Base, st_fragment_program::bitmap_program, st_fragment_program::bitmap_sampler, find_free_bit(), st_context::fp, make_bitmap_fragment_program(), st_reference_fragprog(), and st_translate_fragment_program().

00184 {
00185    struct st_context *st = ctx->st;
00186    struct st_fragment_program *stfp = st->fp;
00187 
00188    if (!stfp->bitmap_program) {
00189       /*
00190        * Generate new program which is the user-defined program prefixed
00191        * with the bitmap sampler/kill instructions.
00192        */
00193       struct st_fragment_program *bitmap_prog;
00194       uint sampler;
00195 
00196       sampler = find_free_bit(st->fp->Base.Base.SamplersUsed);
00197       bitmap_prog = make_bitmap_fragment_program(ctx, sampler);
00198 
00199       stfp->bitmap_program = (struct st_fragment_program *)
00200          _mesa_combine_programs(ctx,
00201                                 &bitmap_prog->Base.Base, &stfp->Base.Base);
00202       stfp->bitmap_program->bitmap_sampler = sampler;
00203 
00204       /* done with this after combining */
00205       st_reference_fragprog(st, &bitmap_prog, NULL);
00206 
00207 #if 0
00208       {
00209          struct gl_program *p = &stfp->bitmap_program->Base.Base;
00210          printf("Combined bitmap program:\n");
00211          _mesa_print_program(p);
00212          printf("InputsRead: 0x%x\n", p->InputsRead);
00213          printf("OutputsWritten: 0x%x\n", p->OutputsWritten);
00214          _mesa_print_parameter_list(p->Parameters);
00215       }
00216 #endif
00217 
00218       /* translate to TGSI tokens */
00219       st_translate_fragment_program(st, stfp->bitmap_program, NULL);
00220    }
00221 
00222    return stfp->bitmap_program;
00223 }

static void draw_bitmap_quad ( GLcontext *  ctx,
GLint  x,
GLint  y,
GLfloat  z,
GLsizei  width,
GLsizei  height,
struct pipe_texture pt,
const GLfloat *  color 
) [static]

Render a glBitmap by drawing a textured quad.

Definition at line 442 of file st_cb_bitmap.c.

References assert, st_fragment_program::Base, st_context::bitmap, st_fragment_program::bitmap_sampler, combined_bitmap_fragment_program(), COPY_4V, cso_restore_fragment_shader(), cso_restore_rasterizer(), cso_restore_sampler_textures(), cso_restore_samplers(), cso_restore_vertex_shader(), cso_restore_viewport(), cso_save_fragment_shader(), cso_save_rasterizer(), cso_save_sampler_textures(), cso_save_samplers(), cso_save_vertex_shader(), cso_save_viewport(), cso_set_fragment_shader_handle(), cso_set_rasterizer(), cso_set_sampler_textures(), cso_set_samplers(), cso_set_vertex_shader_handle(), cso_set_viewport(), st_context::ctx, st_fragment_program::driver_shader, pipe_screen::get_param, MAX2, st_context::num_samplers, st_context::num_textures, offset(), PIPE_CAP_MAX_TEXTURE_2D_LEVELS, PIPE_MAX_SAMPLERS, PIPE_PRIM_TRIANGLE_FAN, PIPE_SHADER_FRAGMENT, st_context::rasterizer, st_context::sampler, st_context::sampler_texture, st_context::samplers, pipe_viewport_state::scale, pipe_rasterizer_state::scissor, pipe_context::screen, setup_bitmap_vertex_data(), st_fb_orientation(), st_upload_constants(), st_context::state, pipe_viewport_state::translate, util_draw_vertex_buffer(), st_context::vbuf, st_context::vs, and Y_0_TOP.

00446 {
00447    struct st_context *st = ctx->st;
00448    struct pipe_context *pipe = ctx->st->pipe;
00449    struct cso_context *cso = ctx->st->cso_context;
00450    struct st_fragment_program *stfp;
00451    GLuint maxSize;
00452    GLuint offset;
00453 
00454    stfp = combined_bitmap_fragment_program(ctx);
00455 
00456    /* As an optimization, Mesa's fragment programs will sometimes get the
00457     * primary color from a statevar/constant rather than a varying variable.
00458     * when that's the case, we need to ensure that we use the 'color'
00459     * parameter and not the current attribute color (which may have changed
00460     * through glRasterPos and state validation.
00461     * So, we force the proper color here.  Not elegant, but it works.
00462     */
00463    {
00464       GLfloat colorSave[4];
00465       COPY_4V(colorSave, ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
00466       COPY_4V(ctx->Current.Attrib[VERT_ATTRIB_COLOR0], color);
00467       st_upload_constants(st, stfp->Base.Base.Parameters, PIPE_SHADER_FRAGMENT);
00468       COPY_4V(ctx->Current.Attrib[VERT_ATTRIB_COLOR0], colorSave);
00469    }
00470 
00471 
00472    /* limit checks */
00473    /* XXX if the bitmap is larger than the max texture size, break
00474     * it up into chunks.
00475     */
00476    maxSize = 1 << (pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
00477    assert(width <= (GLsizei)maxSize);
00478    assert(height <= (GLsizei)maxSize);
00479 
00480    cso_save_rasterizer(cso);
00481    cso_save_samplers(cso);
00482    cso_save_sampler_textures(cso);
00483    cso_save_viewport(cso);
00484    cso_save_fragment_shader(cso);
00485    cso_save_vertex_shader(cso);
00486 
00487    /* rasterizer state: just scissor */
00488    st->bitmap.rasterizer.scissor = ctx->Scissor.Enabled;
00489    cso_set_rasterizer(cso, &st->bitmap.rasterizer);
00490 
00491    /* fragment shader state: TEX lookup program */
00492    cso_set_fragment_shader_handle(cso, stfp->driver_shader);
00493 
00494    /* vertex shader state: position + texcoord pass-through */
00495    cso_set_vertex_shader_handle(cso, st->bitmap.vs);
00496 
00497    /* user samplers, plus our bitmap sampler */
00498    {
00499       struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
00500       uint num = MAX2(stfp->bitmap_sampler + 1, st->state.num_samplers);
00501       uint i;
00502       for (i = 0; i < st->state.num_samplers; i++) {
00503          samplers[i] = &st->state.samplers[i];
00504       }
00505       samplers[stfp->bitmap_sampler] = &st->bitmap.sampler;
00506       cso_set_samplers(cso, num, (const struct pipe_sampler_state **) samplers);
00507    }
00508 
00509    /* user textures, plus the bitmap texture */
00510    {
00511       struct pipe_texture *textures[PIPE_MAX_SAMPLERS];
00512       uint num = MAX2(stfp->bitmap_sampler + 1, st->state.num_textures);
00513       memcpy(textures, st->state.sampler_texture, sizeof(textures));
00514       textures[stfp->bitmap_sampler] = pt;
00515       cso_set_sampler_textures(cso, num, textures);
00516    }
00517 
00518    /* viewport state: viewport matching window dims */
00519    {
00520       const struct gl_framebuffer *fb = st->ctx->DrawBuffer;
00521       const GLboolean invert = (st_fb_orientation(fb) == Y_0_TOP);
00522       const GLfloat width = (GLfloat)fb->Width;
00523       const GLfloat height = (GLfloat)fb->Height;
00524       struct pipe_viewport_state vp;
00525       vp.scale[0] =  0.5f * width;
00526       vp.scale[1] = height * (invert ? -0.5f : 0.5f);
00527       vp.scale[2] = 1.0f;
00528       vp.scale[3] = 1.0f;
00529       vp.translate[0] = 0.5f * width;
00530       vp.translate[1] = 0.5f * height;
00531       vp.translate[2] = 0.0f;
00532       vp.translate[3] = 0.0f;
00533       cso_set_viewport(cso, &vp);
00534    }
00535 
00536    /* draw textured quad */
00537    offset = setup_bitmap_vertex_data(st, x, y, width, height,
00538                                      ctx->Current.RasterPos[2],
00539                                      color);
00540 
00541    util_draw_vertex_buffer(pipe, st->bitmap.vbuf, offset,
00542                            PIPE_PRIM_TRIANGLE_FAN,
00543                            4,  /* verts */
00544                            3); /* attribs/vert */
00545 
00546 
00547    /* restore state */
00548    cso_restore_rasterizer(cso);
00549    cso_restore_samplers(cso);
00550    cso_restore_sampler_textures(cso);
00551    cso_restore_viewport(cso);
00552    cso_restore_fragment_shader(cso);
00553    cso_restore_vertex_shader(cso);
00554 }

static int find_free_bit ( uint  bitfield  )  [static]

Definition at line 167 of file st_cb_bitmap.c.

00168 {
00169    int i;
00170    for (i = 0; i < 32; i++) {
00171       if ((bitfield & (1 << i)) == 0) {
00172          return i;
00173       }
00174    }
00175    return -1;
00176 }

static struct st_fragment_program* make_bitmap_fragment_program ( GLcontext *  ctx,
GLuint  samplerIndex 
) [static, read]

Make fragment program for glBitmap: Sample the texture and kill the fragment if the bit is 0.

This program will be combined with the user's fragment program.

Definition at line 113 of file st_cb_bitmap.c.

References assert, st_fragment_program::Base, and st_translate_fragment_program().

00114 {
00115    struct st_fragment_program *stfp;
00116    struct gl_program *p;
00117    GLuint ic = 0;
00118 
00119    p = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
00120    if (!p)
00121       return NULL;
00122 
00123    p->NumInstructions = 3;
00124 
00125    p->Instructions = _mesa_alloc_instructions(p->NumInstructions);
00126    if (!p->Instructions) {
00127       ctx->Driver.DeleteProgram(ctx, p);
00128       return NULL;
00129    }
00130    _mesa_init_instructions(p->Instructions, p->NumInstructions);
00131 
00132    /* TEX tmp0, fragment.texcoord[0], texture[0], 2D; */
00133    p->Instructions[ic].Opcode = OPCODE_TEX;
00134    p->Instructions[ic].DstReg.File = PROGRAM_TEMPORARY;
00135    p->Instructions[ic].DstReg.Index = 0;
00136    p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT;
00137    p->Instructions[ic].SrcReg[0].Index = FRAG_ATTRIB_TEX0;
00138    p->Instructions[ic].TexSrcUnit = samplerIndex;
00139    p->Instructions[ic].TexSrcTarget = TEXTURE_2D_INDEX;
00140    ic++;
00141 
00142    /* KIL if -tmp0 < 0 # texel=0 -> keep / texel=0 -> discard */
00143    p->Instructions[ic].Opcode = OPCODE_KIL;
00144    p->Instructions[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
00145    p->Instructions[ic].SrcReg[0].Index = 0;
00146    p->Instructions[ic].SrcReg[0].NegateBase = NEGATE_XYZW;
00147    ic++;
00148 
00149    /* END; */
00150    p->Instructions[ic++].Opcode = OPCODE_END;
00151 
00152    assert(ic == p->NumInstructions);
00153 
00154    p->InputsRead = FRAG_BIT_TEX0;
00155    p->OutputsWritten = 0x0;
00156    p->SamplersUsed = (1 << samplerIndex);
00157 
00158    stfp = (struct st_fragment_program *) p;
00159    stfp->Base.UsesKill = GL_TRUE;
00160    st_translate_fragment_program(ctx->st, stfp, NULL);
00161 
00162    return stfp;
00163 }

static struct pipe_texture* make_bitmap_texture ( GLcontext *  ctx,
GLsizei  width,
GLsizei  height,
const struct gl_pixelstore_attrib *  unpack,
const GLubyte *  bitmap 
) [static, read]

Create a texture which represents a bitmap image.

Create texture to hold bitmap pattern.

Definition at line 305 of file st_cb_bitmap.c.

References pipe_screen::get_tex_surface, PIPE_BUFFER_USAGE_CPU_WRITE, pipe_surface_reference(), PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_SAMPLER, pipe_context::screen, st_texture_create(), pipe_surface::stride, pipe_screen::surface_map, pipe_screen::surface_unmap, and unpack_bitmap().

00308 {
00309    struct pipe_context *pipe = ctx->st->pipe;
00310    struct pipe_screen *screen = pipe->screen;
00311    struct pipe_surface *surface;
00312    ubyte *dest;
00313    struct pipe_texture *pt;
00314 
00315    /* PBO source... */
00316    bitmap = _mesa_map_bitmap_pbo(ctx, unpack, bitmap);
00317    if (!bitmap) {
00318       return NULL;
00319    }
00320 
00324    pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, ctx->st->bitmap.tex_format,
00325                           0, width, height, 1, 0,
00326                           PIPE_TEXTURE_USAGE_SAMPLER);
00327    if (!pt) {
00328       _mesa_unmap_bitmap_pbo(ctx, unpack);
00329       return NULL;
00330    }
00331 
00332    surface = screen->get_tex_surface(screen, pt, 0, 0, 0,
00333                                      PIPE_BUFFER_USAGE_CPU_WRITE);
00334 
00335    /* map texture surface */
00336    dest = screen->surface_map(screen, surface, PIPE_BUFFER_USAGE_CPU_WRITE);
00337 
00338    /* Put image into texture surface */
00339    memset(dest, 0xff, height * surface->stride);
00340    unpack_bitmap(ctx->st, 0, 0, width, height, unpack, bitmap,
00341                  dest, surface->stride);
00342 
00343    _mesa_unmap_bitmap_pbo(ctx, unpack);
00344 
00345    /* Release surface */
00346    screen->surface_unmap(screen, surface);
00347    pipe_surface_reference(&surface, NULL);
00348 
00349    return pt;
00350 }

static void reset_cache ( struct st_context st  )  [static]

Definition at line 558 of file st_cb_bitmap.c.

References assert, st_context::bitmap, BITMAP_CACHE_HEIGHT, BITMAP_CACHE_WIDTH, bitmap_cache::buffer, st_context::cache, bitmap_cache::empty, pipe_screen::get_tex_surface, st_context::pipe, PIPE_BUFFER_USAGE_CPU_WRITE, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_SAMPLER, pipe_context::screen, st_texture_create(), bitmap_cache::surf, pipe_screen::surface_map, st_context::tex_format, pipe_screen::tex_surface_release, bitmap_cache::texture, bitmap_cache::xmax, bitmap_cache::xmin, bitmap_cache::ymax, and bitmap_cache::ymin.

00559 {
00560    struct pipe_context *pipe = st->pipe;
00561    struct pipe_screen *screen = pipe->screen;
00562    struct bitmap_cache *cache = st->bitmap.cache;
00563 
00564    //memset(cache->buffer, 0xff, sizeof(cache->buffer));
00565    cache->empty = GL_TRUE;
00566 
00567    cache->xmin = 1000000;
00568    cache->xmax = -1000000;
00569    cache->ymin = 1000000;
00570    cache->ymax = -1000000;
00571 
00572    if (cache->surf)
00573       screen->tex_surface_release(screen, &cache->surf);
00574 
00575    assert(!cache->texture);
00576 
00577    /* allocate a new texture */
00578    cache->texture = st_texture_create(st, PIPE_TEXTURE_2D,
00579                                       st->bitmap.tex_format, 0,
00580                                       BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT,
00581                                       1, 0,
00582                                       PIPE_TEXTURE_USAGE_SAMPLER);
00583 
00584    /* Map the texture surface.
00585     * Subsequent glBitmap calls will write into the texture image.
00586     */
00587    cache->surf = screen->get_tex_surface(screen, cache->texture, 0, 0, 0,
00588                                          PIPE_BUFFER_USAGE_CPU_WRITE);
00589    cache->buffer = screen->surface_map(screen, cache->surf,
00590                                        PIPE_BUFFER_USAGE_CPU_WRITE);
00591 
00592    /* init image to all 0xff */
00593    memset(cache->buffer, 0xff, BITMAP_CACHE_WIDTH * BITMAP_CACHE_HEIGHT);
00594 }

static GLuint setup_bitmap_vertex_data ( struct st_context st,
int  x,
int  y,
int  width,
int  height,
float  z,
const float  color[4] 
) [static]

Definition at line 353 of file st_cb_bitmap.c.

References st_context::bitmap, st_context::ctx, st_context::pipe, pipe_buffer_create(), pipe_buffer_map(), pipe_buffer_reference(), pipe_buffer_unmap(), PIPE_BUFFER_USAGE_CPU_WRITE, PIPE_BUFFER_USAGE_VERTEX, pipe_context::screen, st_context::vbuf, st_context::vbuf_slot, and st_context::vertices.

00356 {
00357    struct pipe_context *pipe = st->pipe;
00358    const struct gl_framebuffer *fb = st->ctx->DrawBuffer;
00359    const GLfloat fb_width = (GLfloat)fb->Width;
00360    const GLfloat fb_height = (GLfloat)fb->Height;
00361    const GLfloat x0 = (GLfloat)x;
00362    const GLfloat x1 = (GLfloat)(x + width);
00363    const GLfloat y0 = (GLfloat)y;
00364    const GLfloat y1 = (GLfloat)(y + height);
00365    const GLfloat sLeft = (GLfloat)0.0, sRight = (GLfloat)1.0;
00366    const GLfloat tTop = (GLfloat)0.0, tBot = (GLfloat)1.0 - tTop;
00367    const GLfloat clip_x0 = (GLfloat)(x0 / fb_width * 2.0 - 1.0);
00368    const GLfloat clip_y0 = (GLfloat)(y0 / fb_height * 2.0 - 1.0);
00369    const GLfloat clip_x1 = (GLfloat)(x1 / fb_width * 2.0 - 1.0);
00370    const GLfloat clip_y1 = (GLfloat)(y1 / fb_height * 2.0 - 1.0);
00371    const GLuint max_slots = 4096 / sizeof(st->bitmap.vertices);
00372    GLuint i;
00373 
00374    if (st->bitmap.vbuf_slot >= max_slots) {
00375       pipe_buffer_reference(pipe->screen, &st->bitmap.vbuf, NULL);
00376       st->bitmap.vbuf_slot = 0;
00377    }
00378 
00379    if (!st->bitmap.vbuf) {
00380       st->bitmap.vbuf = pipe_buffer_create(pipe->screen, 32, 
00381                                            PIPE_BUFFER_USAGE_VERTEX,
00382                                            max_slots * sizeof(st->bitmap.vertices));
00383    }
00384 
00385    /* Positions are in clip coords since we need to do clipping in case
00386     * the bitmap quad goes beyond the window bounds.
00387     */
00388    st->bitmap.vertices[0][0][0] = clip_x0;
00389    st->bitmap.vertices[0][0][1] = clip_y0;
00390    st->bitmap.vertices[0][2][0] = sLeft;
00391    st->bitmap.vertices[0][2][1] = tTop;
00392 
00393    st->bitmap.vertices[1][0][0] = clip_x1;
00394    st->bitmap.vertices[1][0][1] = clip_y0;
00395    st->bitmap.vertices[1][2][0] = sRight;
00396    st->bitmap.vertices[1][2][1] = tTop;
00397    
00398    st->bitmap.vertices[2][0][0] = clip_x1;
00399    st->bitmap.vertices[2][0][1] = clip_y1;
00400    st->bitmap.vertices[2][2][0] = sRight;
00401    st->bitmap.vertices[2][2][1] = tBot;
00402    
00403    st->bitmap.vertices[3][0][0] = clip_x0;
00404    st->bitmap.vertices[3][0][1] = clip_y1;
00405    st->bitmap.vertices[3][2][0] = sLeft;
00406    st->bitmap.vertices[3][2][1] = tBot;
00407    
00408    /* same for all verts: */
00409    for (i = 0; i < 4; i++) {
00410       st->bitmap.vertices[i][0][2] = z;
00411       st->bitmap.vertices[i][0][3] = 1.0;
00412       st->bitmap.vertices[i][1][0] = color[0];
00413       st->bitmap.vertices[i][1][1] = color[1];
00414       st->bitmap.vertices[i][1][2] = color[2];
00415       st->bitmap.vertices[i][1][3] = color[3];
00416       st->bitmap.vertices[i][2][2] = 0.0; /*R*/
00417       st->bitmap.vertices[i][2][3] = 1.0; /*Q*/
00418    }
00419 
00420    /* put vertex data into vbuf */
00421    {
00422       char *buf = pipe_buffer_map(pipe->screen, 
00423                                   st->bitmap.vbuf, 
00424                                   PIPE_BUFFER_USAGE_CPU_WRITE);
00425 
00426       memcpy(buf + st->bitmap.vbuf_slot * sizeof st->bitmap.vertices, 
00427              st->bitmap.vertices, 
00428              sizeof st->bitmap.vertices);
00429 
00430       pipe_buffer_unmap(pipe->screen, st->bitmap.vbuf);
00431    }
00432 
00433    return st->bitmap.vbuf_slot++ * sizeof st->bitmap.vertices;
00434 }

static void st_Bitmap ( GLcontext *  ctx,
GLint  x,
GLint  y,
GLsizei  width,
GLsizei  height,
const struct gl_pixelstore_attrib *  unpack,
const GLubyte *  bitmap 
) [static]

Called via ctx->Driver.Bitmap().

Definition at line 721 of file st_cb_bitmap.c.

References accum_bitmap(), assert, st_context::bitmap, st_context::ctx, draw_bitmap_quad(), make_bitmap_texture(), st_context::pipe, PIPE_TEXTURE_2D, pipe_texture_reference(), semantic_names, st_validate_state(), pipe_texture::target, TGSI_SEMANTIC_COLOR, TGSI_SEMANTIC_GENERIC, TGSI_SEMANTIC_POSITION, UseBitmapCache, util_make_vertex_passthrough_shader(), st_context::vert_shader, and st_context::vs.

00723 {
00724    struct st_context *st = ctx->st;
00725    struct pipe_texture *pt;
00726 
00727    if (width == 0 || height == 0)
00728       return;
00729 
00730    st_validate_state(st);
00731 
00732    if (!st->bitmap.vs) {
00733       /* create pass-through vertex shader now */
00734       const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
00735                                       TGSI_SEMANTIC_COLOR,
00736                                       TGSI_SEMANTIC_GENERIC };
00737       const uint semantic_indexes[] = { 0, 0, 0 };
00738       st->bitmap.vs = util_make_vertex_passthrough_shader(st->pipe, 3,
00739                                                           semantic_names,
00740                                                           semantic_indexes,
00741                                                           &st->bitmap.vert_shader);
00742    }
00743 
00744    if (UseBitmapCache && accum_bitmap(st, x, y, width, height, unpack, bitmap))
00745       return;
00746 
00747    pt = make_bitmap_texture(ctx, width, height, unpack, bitmap);
00748    if (pt) {
00749       assert(pt->target == PIPE_TEXTURE_2D);
00750       draw_bitmap_quad(ctx, x, y, ctx->Current.RasterPos[2],
00751                        width, height, pt,
00752                        st->ctx->Current.RasterColor);
00753       /* release/free the texture */
00754       pipe_texture_reference(&pt, NULL);
00755    }
00756 }

void st_destroy_bitmap ( struct st_context st  ) 

Per-context tear-down.

Definition at line 809 of file st_cb_bitmap.c.

References st_context::bitmap, st_context::cache, st_context::cso_context, cso_delete_vertex_shader(), FREE, st_context::pipe, pipe_buffer_destroy(), pipe_texture_release(), pipe_context::screen, bitmap_cache::surf, pipe_screen::surface_unmap, pipe_screen::tex_surface_release, util_free_shader(), st_context::vbuf, st_context::vert_shader, and st_context::vs.

00810 {
00811    struct pipe_context *pipe = st->pipe;
00812    struct pipe_screen *screen = pipe->screen;
00813    struct bitmap_cache *cache = st->bitmap.cache;
00814 
00815    screen->surface_unmap(screen, cache->surf);
00816    screen->tex_surface_release(screen, &cache->surf);
00817 
00818    if (st->bitmap.vs) {
00819       cso_delete_vertex_shader(st->cso_context, st->bitmap.vs);
00820       st->bitmap.vs = NULL;
00821    }
00822    util_free_shader(&st->bitmap.vert_shader);
00823 
00824    if (st->bitmap.vbuf) {
00825       pipe_buffer_destroy(pipe->screen, st->bitmap.vbuf);
00826       st->bitmap.vbuf = NULL;
00827    }
00828 
00829    if (st->bitmap.cache) {
00830       pipe_texture_release(&st->bitmap.cache->texture);
00831       FREE(st->bitmap.cache);
00832       st->bitmap.cache = NULL;
00833    }
00834 }

void st_flush_bitmap ( struct st_context st  ) 

Definition at line 645 of file st_cb_bitmap.c.

References st_context::bitmap, st_context::pipe, pipe_buffer_reference(), pipe_context::screen, st_flush_bitmap_cache(), st_context::vbuf, and st_context::vbuf_slot.

00646 {
00647    st_flush_bitmap_cache(st);
00648 
00649    /* Release vertex buffer to avoid synchronous rendering if we were
00650     * to map it in the next frame.
00651     */
00652    pipe_buffer_reference(st->pipe->screen, &st->bitmap.vbuf, NULL);
00653    st->bitmap.vbuf_slot = 0;
00654 }

void st_flush_bitmap_cache ( struct st_context st  ) 

If there's anything in the bitmap cache, draw/flush it now.

Definition at line 601 of file st_cb_bitmap.c.

References assert, st_context::bitmap, BITMAP_CACHE_HEIGHT, BITMAP_CACHE_WIDTH, bitmap_cache::buffer, st_context::cache, bitmap_cache::color, st_context::ctx, draw_bitmap_quad(), st_context::pipe, pipe_texture_reference(), reset_cache(), pipe_context::screen, bitmap_cache::surf, pipe_screen::surface_unmap, pipe_screen::tex_surface_release, bitmap_cache::texture, bitmap_cache::xmax, bitmap_cache::xmin, bitmap_cache::xpos, and bitmap_cache::ypos.

00602 {
00603    if (!st->bitmap.cache->empty) {
00604       struct bitmap_cache *cache = st->bitmap.cache;
00605 
00606       if (st->ctx->DrawBuffer) {
00607          struct pipe_context *pipe = st->pipe;
00608          struct pipe_screen *screen = pipe->screen;
00609 
00610          assert(cache->xmin <= cache->xmax);
00611  
00612 /*         printf("flush size %d x %d  at %d, %d\n",
00613                 cache->xmax - cache->xmin,
00614                 cache->ymax - cache->ymin,
00615                 cache->xpos, cache->ypos);
00616 */
00617 
00618          /* The texture surface has been mapped until now.
00619           * So unmap and release the texture surface before drawing.
00620           */
00621          screen->surface_unmap(screen, cache->surf);
00622          cache->buffer = NULL;
00623 
00624          screen->tex_surface_release(screen, &cache->surf);
00625 
00626          draw_bitmap_quad(st->ctx,
00627                           cache->xpos,
00628                           cache->ypos,
00629                           st->ctx->Current.RasterPos[2],
00630                           BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT,
00631                           cache->texture,
00632                           cache->color);
00633       }
00634 
00635       /* release/free the texture */
00636       pipe_texture_reference(&cache->texture, NULL);
00637 
00638       reset_cache(st);
00639    }
00640 }

void st_init_bitmap ( struct st_context st  ) 

Per-context init.

Definition at line 769 of file st_cb_bitmap.c.

References assert, st_context::bitmap, pipe_rasterizer_state::bypass_vs, st_context::cache, CALLOC_STRUCT, pipe_rasterizer_state::gl_rasterization_rules, pipe_screen::is_format_supported, pipe_sampler_state::mag_img_filter, pipe_sampler_state::min_img_filter, pipe_sampler_state::min_mip_filter, pipe_sampler_state::normalized_coords, st_context::pipe, PIPE_FORMAT_I8_UNORM, PIPE_TEX_FILTER_NEAREST, PIPE_TEX_MIPFILTER_NONE, PIPE_TEX_WRAP_CLAMP, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_SAMPLER, st_context::rasterizer, reset_cache(), st_context::sampler, pipe_context::screen, st_context::tex_format, pipe_sampler_state::wrap_r, pipe_sampler_state::wrap_s, and pipe_sampler_state::wrap_t.

00770 {
00771    struct pipe_sampler_state *sampler = &st->bitmap.sampler;
00772    struct pipe_context *pipe = st->pipe;
00773    struct pipe_screen *screen = pipe->screen;
00774 
00775    /* init sampler state once */
00776    memset(sampler, 0, sizeof(*sampler));
00777    sampler->wrap_s = PIPE_TEX_WRAP_CLAMP;
00778    sampler->wrap_t = PIPE_TEX_WRAP_CLAMP;
00779    sampler->wrap_r = PIPE_TEX_WRAP_CLAMP;
00780    sampler->min_img_filter = PIPE_TEX_FILTER_NEAREST;
00781    sampler->min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
00782    sampler->mag_img_filter = PIPE_TEX_FILTER_NEAREST;
00783    sampler->normalized_coords = 1;
00784 
00785    /* init baseline rasterizer state once */
00786    memset(&st->bitmap.rasterizer, 0, sizeof(st->bitmap.rasterizer));
00787    st->bitmap.rasterizer.gl_rasterization_rules = 1;
00788    st->bitmap.rasterizer.bypass_vs = 1;
00789 
00790    /* find a usable texture format */
00791    if (screen->is_format_supported(screen, PIPE_FORMAT_I8_UNORM, PIPE_TEXTURE_2D, 
00792                                    PIPE_TEXTURE_USAGE_SAMPLER, 0)) {
00793       st->bitmap.tex_format = PIPE_FORMAT_I8_UNORM;
00794    }
00795    else {
00796       /* XXX support more formats */
00797       assert(0);
00798    }
00799 
00800    /* alloc bitmap cache object */
00801    st->bitmap.cache = CALLOC_STRUCT(bitmap_cache);
00802 
00803    reset_cache(st);
00804 }

void st_init_bitmap_functions ( struct dd_function_table *  functions  ) 

Per-context init.

Definition at line 761 of file st_cb_bitmap.c.

References st_Bitmap().

00762 {
00763    functions->Bitmap = st_Bitmap;
00764 }

static void unpack_bitmap ( struct st_context st,
GLint  px,
GLint  py,
GLsizei  width,
GLsizei  height,
const struct gl_pixelstore_attrib *  unpack,
const GLubyte *  bitmap,
ubyte destBuffer,
uint  destStride 
) [static]

Copy user-provide bitmap bits into texture buffer, expanding bits into texels.

"On" bits will set texels to 0xff. "Off" bits will not modify texels. Note that the image is actually going to be upside down in the texture. We deal with that with texcoords.

Definition at line 235 of file st_cb_bitmap.c.

References SET_PIXEL.

00240 {
00241    GLint row, col;
00242 
00243 #define SET_PIXEL(COL, ROW) \
00244    destBuffer[(py + (ROW)) * destStride + px + (COL)] = 0x0;
00245 
00246    for (row = 0; row < height; row++) {
00247       const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
00248                  bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
00249 
00250       if (unpack->LsbFirst) {
00251          /* Lsb first */
00252          GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
00253          for (col = 0; col < width; col++) {
00254 
00255             if (*src & mask) {
00256                SET_PIXEL(col, row);
00257             }
00258 
00259             if (mask == 128U) {
00260                src++;
00261                mask = 1U;
00262             }
00263             else {
00264                mask = mask << 1;
00265             }
00266          }
00267 
00268          /* get ready for next row */
00269          if (mask != 1)
00270             src++;
00271       }
00272       else {
00273          /* Msb first */
00274          GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
00275          for (col = 0; col < width; col++) {
00276 
00277             if (*src & mask) {
00278                SET_PIXEL(col, row);
00279             }
00280 
00281             if (mask == 1U) {
00282                src++;
00283                mask = 128U;
00284             }
00285             else {
00286                mask = mask >> 1;
00287             }
00288          }
00289 
00290          /* get ready for next row */
00291          if (mask != 128)
00292             src++;
00293       }
00294 
00295    } /* row */
00296 
00297 #undef SET_PIXEL
00298 }


Variable Documentation

GLboolean UseBitmapCache = GL_TRUE [static]

glBitmaps are drawn as textured quads.

The user's bitmap pattern is stored in a texture image. An alpha8 texture format is used. The fragment shader samples a bit (texel) from the texture, then discards the fragment if the bit is off.

Note that we actually store the inverse image of the bitmap to simplify the fragment program. An "on" bit gets stored as texel=0x0 and an "off" bit is stored as texel=0xff. Then we kill the fragment if the negated texel value is less than zero. The bitmap cache attempts to accumulate multiple glBitmap calls in a buffer which is then rendered en mass upon a flush, state change, etc. A wide, short buffer is used to target the common case of a series of glBitmap calls being used to draw text.

Definition at line 80 of file st_cb_bitmap.c.


Generated on Tue Sep 29 06:25:51 2009 for Gallium3D by  doxygen 1.5.4