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_program * | make_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_program * | combined_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_texture * | make_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 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; |
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.
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 }
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.