From 1ecb2e4a7a5881d5a98679b421d78fd11c729ebc Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 26 Mar 2008 09:02:54 -0600 Subject: gallium: need to call st_validate_state() in Bitmap() --- src/mesa/state_tracker/st_cb_bitmap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/mesa/state_tracker/st_cb_bitmap.c') diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index 6e59439874..0291b03143 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -475,6 +475,8 @@ st_Bitmap(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, struct st_context *st = ctx->st; struct pipe_texture *pt; + st_validate_state(st); + stfp = combined_bitmap_fragment_program(ctx); if (!st->bitmap.vs) { -- cgit v1.2.3 From 6f8286163c79a8187c2912a9b673a6f11f4f60c6 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 27 Mar 2008 15:42:52 -0600 Subject: gallium: Update calls to the simple shader functions --- src/mesa/state_tracker/st_cb_bitmap.c | 4 +++- src/mesa/state_tracker/st_cb_clear.c | 5 +++-- src/mesa/state_tracker/st_context.h | 3 +++ 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'src/mesa/state_tracker/st_cb_bitmap.c') diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index 0291b03143..64b1882424 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -487,13 +487,15 @@ st_Bitmap(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, const uint semantic_indexes[] = { 0, 0, 0 }; st->bitmap.vs = util_make_vertex_passthrough_shader(st->pipe, 3, semantic_names, - semantic_indexes); + semantic_indexes, + &st->bitmap.vert_shader); } st_validate_state(st); pt = make_bitmap_texture(ctx, width, height, unpack, bitmap); if (pt) { + assert(pt->target == PIPE_TEXTURE_2D); draw_bitmap_quad(ctx, x, y, ctx->Current.RasterPos[2], width, height, pt, stfp); diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index 5ca15df602..ec8d3e1022 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -251,7 +251,7 @@ clear_with_quad(GLcontext *ctx, /* fragment shader state: color pass-through program */ if (!st->clear.fs) { - st->clear.fs = util_make_fragment_passthrough_shader(pipe); + st->clear.fs = util_make_fragment_passthrough_shader(pipe, &st->clear.frag_shader); } pipe->bind_fs_state(pipe, st->clear.fs); @@ -264,7 +264,8 @@ clear_with_quad(GLcontext *ctx, const uint semantic_indexes[] = { 0, 0 }; st->clear.vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names, - semantic_indexes); + semantic_indexes, + &st->clear.vert_shader); } pipe->bind_vs_state(pipe, st->clear.vs); #endif diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 2d37086799..f235c194b7 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -147,6 +147,7 @@ struct st_context struct st_fragment_program *program; /**< bitmap tex/kil program */ GLuint user_prog_sn; /**< user fragment program serial no. */ struct st_fragment_program *combined_prog; + struct pipe_shader_state vert_shader; void *vs; float vertices[4][3][4]; /**< vertex pos + color + texcoord */ struct pipe_buffer *vbuf; @@ -154,6 +155,8 @@ struct st_context /** for glClear */ struct { + struct pipe_shader_state vert_shader; + struct pipe_shader_state frag_shader; void *vs; void *fs; float vertices[4][2][4]; /**< vertex pos + color */ -- cgit v1.2.3 From c62b197b528293abb56b099503344e3cdd7d6c40 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 28 Mar 2008 14:53:47 -0600 Subject: gallium: implement a glBitmap cache The bitmap cache attempts to accumulate a series of glBitmap calls in a buffer to effectively render a whole bunch of bitmaps at once. The cache can be disabled, if needed, by setting UseBitmapCache=GL_FALSE. --- src/mesa/state_tracker/st_atom.c | 3 + src/mesa/state_tracker/st_cb_bitmap.c | 234 ++++++++++++++++++++++++++++++++-- src/mesa/state_tracker/st_cb_bitmap.h | 5 + src/mesa/state_tracker/st_cb_flush.c | 3 + src/mesa/state_tracker/st_context.c | 1 + src/mesa/state_tracker/st_context.h | 2 + 6 files changed, 236 insertions(+), 12 deletions(-) (limited to 'src/mesa/state_tracker/st_cb_bitmap.c') diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c index 0e22a2fa6e..40e4142631 100644 --- a/src/mesa/state_tracker/st_atom.c +++ b/src/mesa/state_tracker/st_atom.c @@ -32,6 +32,7 @@ #include "pipe/p_defines.h" #include "st_context.h" #include "st_atom.h" +#include "st_cb_bitmap.h" #include "st_program.h" @@ -147,6 +148,8 @@ void st_validate_state( struct st_context *st ) struct st_state_flags *state = &st->dirty; GLuint i; + st_flush_bitmap_cache(st); + check_program_state( st ); if (state->st == 0) diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index 64b1882424..e46dcbf661 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -59,6 +59,31 @@ +/** + * 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. + */ +static GLboolean UseBitmapCache = 0*GL_TRUE; + + +#define BITMAP_CACHE_WIDTH 512 +#define BITMAP_CACHE_HEIGHT 32 + +struct bitmap_cache +{ + /** An I8 texture image: */ + GLubyte buffer[BITMAP_CACHE_HEIGHT][BITMAP_CACHE_WIDTH]; + GLboolean empty; + /** Window pos to render the cached image */ + GLint xpos, ypos; + struct pipe_texture *texture; +}; + + + + /** * Make fragment program for glBitmap: * Sample the texture and kill the fragment if the bit is 0. @@ -390,16 +415,18 @@ setup_bitmap_vertex_data(struct st_context *st, static void draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, GLsizei width, GLsizei height, - struct pipe_texture *pt, - struct st_fragment_program *stfp) + struct pipe_texture *pt) { struct st_context *st = ctx->st; struct pipe_context *pipe = ctx->st->pipe; struct cso_context *cso = ctx->st->cso_context; + struct st_fragment_program *stfp; GLuint maxSize; + stfp = combined_bitmap_fragment_program(ctx); + /* limit checks */ - /* XXX if DrawPixels image is larger than max texture size, break + /* XXX if the bitmap is larger than the max texture size, break * it up into chunks. */ maxSize = 1 << (pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1); @@ -467,18 +494,185 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, +static void +init_bitmap_cache(struct st_context *st) +{ + struct pipe_context *pipe = st->pipe; + struct pipe_screen *screen = pipe->screen; + enum pipe_format format; + + st->bitmap.cache = CALLOC_STRUCT(bitmap_cache); + if (!st->bitmap.cache) + return; + + /* find a usable texture format */ + if (screen->is_format_supported(screen, PIPE_FORMAT_U_I8, PIPE_TEXTURE)) { + format = PIPE_FORMAT_U_I8; + } + else { + /* XXX support more formats */ + assert(0); + } + + st->bitmap.cache->texture + = st_texture_create(st, PIPE_TEXTURE_2D, format, 0, + BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT, 1, 0); + if (!st->bitmap.cache->texture) { + FREE(st->bitmap.cache); + st->bitmap.cache = NULL; + return; + } + + st->bitmap.cache->empty = GL_TRUE; +} + + +/** + * If there's anything in the bitmap cache, draw/flush it now. + */ +void +st_flush_bitmap_cache(struct st_context *st) +{ + if (!st->bitmap.cache->empty) { + struct pipe_context *pipe = st->pipe; + struct pipe_screen *screen = pipe->screen; + struct pipe_surface *surf; + void *dest; + + /* update the texture map image */ + surf = screen->get_tex_surface(screen, st->bitmap.cache->texture, 0, 0, 0); + dest = pipe_surface_map(surf); + memcpy(dest, st->bitmap.cache->buffer, sizeof(st->bitmap.cache->buffer)); + pipe_surface_unmap(surf); + pipe_surface_reference(&surf, NULL); + + pipe->texture_update(pipe, st->bitmap.cache->texture, 0, 0x1); + + draw_bitmap_quad(st->ctx, + st->bitmap.cache->xpos, + st->bitmap.cache->ypos, + st->ctx->Current.RasterPos[2], + BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT, + st->bitmap.cache->texture); + + memset(st->bitmap.cache->buffer, 0, sizeof(st->bitmap.cache->buffer)); + st->bitmap.cache->empty = GL_TRUE; + } +} + + +/** + * Try to accumulate this glBitmap call in the bitmap cache. + * \return GL_TRUE for success, GL_FALSE if bitmap is too large, etc. + */ +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 ) +{ + int row, col; + int px = -999, py; + + if (width > BITMAP_CACHE_WIDTH || + height > BITMAP_CACHE_HEIGHT) + return GL_FALSE; /* too big to cache */ + + if (!st->bitmap.cache->empty) { + px = x - st->bitmap.cache->xpos; /* pos in buffer */ + py = y - st->bitmap.cache->ypos; + if (px < 0 || px + width > BITMAP_CACHE_WIDTH || + py < 0 || py + height > BITMAP_CACHE_HEIGHT) { + /* This bitmap would extend beyond cache bounds, + * so flush and continue. + */ + st_flush_bitmap_cache(st); + } + } + + if (st->bitmap.cache->empty) { + /* Initialize. Center bitmap vertically in the buffer. */ + px = 0; + py = (BITMAP_CACHE_HEIGHT - height) / 2; + st->bitmap.cache->xpos = x; + st->bitmap.cache->ypos = y - py; + st->bitmap.cache->empty = GL_FALSE; + } + + assert(px != -999); + + /* XXX try to combine this code with code in make_bitmap_texture() */ +#define SET_PIXEL(COL, ROW) \ + st->bitmap.cache->buffer[py + (ROW)][px + (COL)] = 0xff; + + for (row = 0; row < height; row++) { + const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack, + bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0); + + if (unpack->LsbFirst) { + /* Lsb first */ + GLubyte mask = 1U << (unpack->SkipPixels & 0x7); + for (col = 0; col < width; col++) { + + if (*src & mask) { + SET_PIXEL(col, row); + } + + if (mask == 128U) { + src++; + mask = 1U; + } + else { + mask = mask << 1; + } + } + + /* get ready for next row */ + if (mask != 1) + src++; + } + else { + /* Msb first */ + GLubyte mask = 128U >> (unpack->SkipPixels & 0x7); + for (col = 0; col < width; col++) { + + if (*src & mask) { + SET_PIXEL(col, row); + } + + if (mask == 1U) { + src++; + mask = 128U; + } + else { + mask = mask >> 1; + } + } + + /* get ready for next row */ + if (mask != 128) + src++; + } + + } /* row */ + + return GL_TRUE; /* accumulated */ +} + + + +/** + * Called via ctx->Driver.Bitmap() + */ static void st_Bitmap(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap ) { - struct st_fragment_program *stfp; struct st_context *st = ctx->st; struct pipe_texture *pt; st_validate_state(st); - stfp = combined_bitmap_fragment_program(ctx); - if (!st->bitmap.vs) { /* create pass-through vertex shader now */ const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, @@ -491,26 +685,36 @@ st_Bitmap(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, &st->bitmap.vert_shader); } - st_validate_state(st); + if (UseBitmapCache && accum_bitmap(st, x, y, width, height, unpack, bitmap)) + return; pt = make_bitmap_texture(ctx, width, height, unpack, bitmap); if (pt) { assert(pt->target == PIPE_TEXTURE_2D); draw_bitmap_quad(ctx, x, y, ctx->Current.RasterPos[2], - width, height, - pt, stfp); + width, height, pt); pipe_texture_reference(&pt, NULL); } } - -void st_init_bitmap_functions(struct dd_function_table *functions) +/** Per-context init */ +void +st_init_bitmap_functions(struct dd_function_table *functions) { functions->Bitmap = st_Bitmap; } +/** Per-context init */ +void +st_init_bitmap(struct st_context *st) +{ + init_bitmap_cache(st); +} + + +/** Per-context tear-down */ void st_destroy_bitmap(struct st_context *st) { @@ -528,9 +732,15 @@ st_destroy_bitmap(struct st_context *st) pipe->delete_vs_state(pipe, st->bitmap.vs); st->bitmap.vs = NULL; } + if (st->bitmap.vbuf) { pipe->winsys->buffer_destroy(pipe->winsys, st->bitmap.vbuf); st->bitmap.vbuf = NULL; } -} + if (st->bitmap.cache) { + pipe_texture_release(&st->bitmap.cache->texture); + FREE(st->bitmap.cache); + st->bitmap.cache = NULL; + } +} diff --git a/src/mesa/state_tracker/st_cb_bitmap.h b/src/mesa/state_tracker/st_cb_bitmap.h index ac19e0ebb1..aae11d34c9 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.h +++ b/src/mesa/state_tracker/st_cb_bitmap.h @@ -33,9 +33,14 @@ extern void st_init_bitmap_functions(struct dd_function_table *functions); +extern void +st_init_bitmap(struct st_context *st); extern void st_destroy_bitmap(struct st_context *st); +extern void +st_flush_bitmap_cache(struct st_context *st); + #endif /* ST_CB_BITMAP_H */ diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c index a536a059bd..e321b401e2 100644 --- a/src/mesa/state_tracker/st_cb_flush.c +++ b/src/mesa/state_tracker/st_cb_flush.c @@ -35,6 +35,7 @@ #include "main/macros.h" #include "main/context.h" #include "st_context.h" +#include "st_cb_bitmap.h" #include "st_cb_flush.h" #include "st_cb_fbo.h" #include "st_public.h" @@ -48,6 +49,8 @@ void st_flush( struct st_context *st, uint pipeFlushFlags, { FLUSH_VERTICES(st->ctx, 0); + st_flush_bitmap_cache(st); + st->pipe->flush( st->pipe, pipeFlushFlags, fence ); } diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 726e06d7c2..a20195f2de 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -109,6 +109,7 @@ st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe ) st->cso_context = cso_create_context(pipe); st_init_atoms( st ); + st_init_bitmap(st); st_init_draw( st ); st_init_generate_mipmap(st); st_init_blit(st); diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index f235c194b7..85e3d47e1a 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -42,6 +42,7 @@ struct cso_cache; struct cso_blend; struct gen_mipmap_state; struct blit_state; +struct bitmap_cache; #define ST_NEW_MESA 0x1 /* Mesa state has changed */ @@ -151,6 +152,7 @@ struct st_context void *vs; float vertices[4][3][4]; /**< vertex pos + color + texcoord */ struct pipe_buffer *vbuf; + struct bitmap_cache *cache; } bitmap; /** for glClear */ -- cgit v1.2.3 From 7292db2138001b48bba006cc08e9ff7091d16559 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 28 Mar 2008 14:56:05 -0600 Subject: gallium: disable a debug hack --- src/mesa/state_tracker/st_cb_bitmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/state_tracker/st_cb_bitmap.c') diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index e46dcbf661..464e22d576 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -65,7 +65,7 @@ * A wide, short buffer is used to target the common case of a series * of glBitmap calls being used to draw text. */ -static GLboolean UseBitmapCache = 0*GL_TRUE; +static GLboolean UseBitmapCache = GL_TRUE; #define BITMAP_CACHE_WIDTH 512 -- cgit v1.2.3 From f6908a766dce645d610ff04bb49eaa8c5ee9e65a Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 28 Mar 2008 18:18:55 -0600 Subject: gallium: added an (int) cast in setup_bitmap_vertex_data() to fix a signed/unsigned arithmetic problem Negative values became very large uints. --- src/mesa/state_tracker/st_cb_bitmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/state_tracker/st_cb_bitmap.c') diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index 464e22d576..b600b92dc6 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -351,7 +351,7 @@ setup_bitmap_vertex_data(struct st_context *st, const GLboolean invert = (st_fb_orientation(fb) == Y_0_TOP); const GLfloat x0 = x; const GLfloat x1 = x + width; - const GLfloat y0 = invert ? (fb->Height - y - height) : y; + const GLfloat y0 = invert ? ((int) fb->Height - y - height) : y; const GLfloat y1 = invert ? (y0 + height) : y + height; const GLfloat bias = st->bitmap_texcoord_bias; const GLfloat xBias = bias / (x1-x0); -- cgit v1.2.3 From 737e34aee598f32f8ff078ba823ed149b282ebc8 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 28 Mar 2008 18:41:10 -0600 Subject: gallium: begin some bounding box code for bitmap cache --- src/mesa/state_tracker/st_cb_bitmap.c | 72 +++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 20 deletions(-) (limited to 'src/mesa/state_tracker/st_cb_bitmap.c') diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index b600b92dc6..ec56b25f7c 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -73,12 +73,14 @@ static GLboolean UseBitmapCache = GL_TRUE; struct bitmap_cache { - /** An I8 texture image: */ - GLubyte buffer[BITMAP_CACHE_HEIGHT][BITMAP_CACHE_WIDTH]; - GLboolean empty; /** Window pos to render the cached image */ GLint xpos, ypos; + /** Bounds of region used in window coords */ + GLint xmin, ymin, xmax, ymax; struct pipe_texture *texture; + GLboolean empty; + /** An I8 texture image: */ + GLubyte buffer[BITMAP_CACHE_HEIGHT][BITMAP_CACHE_WIDTH]; }; @@ -493,6 +495,18 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, } +static void +reset_cache(struct st_context *st) +{ + memset(st->bitmap.cache->buffer, 0, sizeof(st->bitmap.cache->buffer)); + st->bitmap.cache->empty = GL_TRUE; + + st->bitmap.cache->xmin = 1000000; + st->bitmap.cache->xmax = -1000000; + st->bitmap.cache->ymin = 1000000; + st->bitmap.cache->ymax = -1000000; +} + static void init_bitmap_cache(struct st_context *st) @@ -523,7 +537,7 @@ init_bitmap_cache(struct st_context *st) return; } - st->bitmap.cache->empty = GL_TRUE; + reset_cache(st); } @@ -534,29 +548,37 @@ void st_flush_bitmap_cache(struct st_context *st) { if (!st->bitmap.cache->empty) { + struct bitmap_cache *cache = st->bitmap.cache; struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; struct pipe_surface *surf; void *dest; + assert(cache->xmin <= cache->xmax); + /* + printf("flush size %d x %d at %d, %d\n", + cache->xmax - cache->xmin, + cache->ymax - cache->ymin, + cache->xpos, cache->ypos); + */ + /* update the texture map image */ - surf = screen->get_tex_surface(screen, st->bitmap.cache->texture, 0, 0, 0); + surf = screen->get_tex_surface(screen, cache->texture, 0, 0, 0); dest = pipe_surface_map(surf); - memcpy(dest, st->bitmap.cache->buffer, sizeof(st->bitmap.cache->buffer)); + memcpy(dest, cache->buffer, sizeof(cache->buffer)); pipe_surface_unmap(surf); pipe_surface_reference(&surf, NULL); - pipe->texture_update(pipe, st->bitmap.cache->texture, 0, 0x1); + pipe->texture_update(pipe, cache->texture, 0, 0x1); draw_bitmap_quad(st->ctx, - st->bitmap.cache->xpos, - st->bitmap.cache->ypos, + cache->xpos, + cache->ypos, st->ctx->Current.RasterPos[2], BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT, - st->bitmap.cache->texture); + cache->texture); - memset(st->bitmap.cache->buffer, 0, sizeof(st->bitmap.cache->buffer)); - st->bitmap.cache->empty = GL_TRUE; + reset_cache(st); } } @@ -571,6 +593,7 @@ accum_bitmap(struct st_context *st, const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap ) { + struct bitmap_cache *cache = st->bitmap.cache; int row, col; int px = -999, py; @@ -578,9 +601,9 @@ accum_bitmap(struct st_context *st, height > BITMAP_CACHE_HEIGHT) return GL_FALSE; /* too big to cache */ - if (!st->bitmap.cache->empty) { - px = x - st->bitmap.cache->xpos; /* pos in buffer */ - py = y - st->bitmap.cache->ypos; + if (!cache->empty) { + px = x - cache->xpos; /* pos in buffer */ + py = y - cache->ypos; if (px < 0 || px + width > BITMAP_CACHE_WIDTH || py < 0 || py + height > BITMAP_CACHE_HEIGHT) { /* This bitmap would extend beyond cache bounds, @@ -590,20 +613,29 @@ accum_bitmap(struct st_context *st, } } - if (st->bitmap.cache->empty) { + if (cache->empty) { /* Initialize. Center bitmap vertically in the buffer. */ px = 0; py = (BITMAP_CACHE_HEIGHT - height) / 2; - st->bitmap.cache->xpos = x; - st->bitmap.cache->ypos = y - py; - st->bitmap.cache->empty = GL_FALSE; + cache->xpos = x; + cache->ypos = y - py; + cache->empty = GL_FALSE; } assert(px != -999); + if (x < cache->xmin) + cache->xmin = x; + if (y < cache->ymin) + cache->ymin = y; + if (x + width > cache->xmax) + cache->xmax = x + width; + if (y + height > cache->ymax) + cache->ymax = y + height; + /* XXX try to combine this code with code in make_bitmap_texture() */ #define SET_PIXEL(COL, ROW) \ - st->bitmap.cache->buffer[py + (ROW)][px + (COL)] = 0xff; + cache->buffer[py + (ROW)][px + (COL)] = 0xff; for (row = 0; row < height; row++) { const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack, -- cgit v1.2.3