#include "ffb_context.h"
#include "ffb_state.h"
#include "ffb_lock.h"
#include "ffb_bitmap.h"
#include "swrast/swrast.h"
#include "image.h"
#include "macros.h"
#undef FFB_BITMAP_TRACE
static void
ffb_bitmap(GLcontext *ctx, GLint px, GLint py,
GLsizei width, GLsizei height,
const struct gl_pixelstore_attrib *unpack,
const GLubyte *bitmap)
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
ffb_fbcPtr ffb = fmesa->regs;
__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
unsigned int ppc, pixel;
GLint row, col, row_stride;
const GLubyte *src;
char *buf;
if (fmesa->bad_fragment_attrs != 0)
_swrast_Bitmap(ctx, px, py, width,
height, unpack, bitmap);
pixel = (((((GLuint)(ctx->Current.RasterColor[0] * 255.0f)) & 0xff) << 0) |
((((GLuint)(ctx->Current.RasterColor[1] * 255.0f)) & 0xff) << 8) |
((((GLuint)(ctx->Current.RasterColor[2] * 255.0f)) & 0xff) << 16) |
((((GLuint)(ctx->Current.RasterColor[3] * 255.0f)) & 0xff) << 24));
#ifdef FFB_BITMAP_TRACE
fprintf(stderr, "ffb_bitmap: ppc(%08x) fbc(%08x) cmp(%08x) pixel(%08x)\n",
fmesa->ppc, fmesa->fbc, fmesa->cmp, pixel);
#endif
LOCK_HARDWARE(fmesa);
fmesa->hw_locked = 1;
if (fmesa->state_dirty)
ffbSyncHardware(fmesa);
ppc = fmesa->ppc;
FFBFifo(fmesa, 4);
ffb->ppc = ((ppc &
~(FFB_PPC_TBE_MASK | FFB_PPC_ZS_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK))
| (FFB_PPC_TBE_TRANSPARENT | FFB_PPC_ZS_CONST | FFB_PPC_CS_CONST |
(ctx->Color.BlendEnabled ? FFB_PPC_XS_CONST : FFB_PPC_XS_WID)));
ffb->constz = ((GLuint) (ctx->Current.RasterPos[2] * 0x0fffffff));
ffb->fg = pixel;
ffb->fontinc = (0 << 16) | 32;
buf = (char *)(fmesa->sfb32 + (dPriv->x << 2) + (dPriv->y << 13));
row_stride = (unpack->Alignment * CEILING(width, 8 * unpack->Alignment));
src = (const GLubyte *) (bitmap +
(unpack->SkipRows * row_stride) +
(unpack->SkipPixels / 8));
if (unpack->LsbFirst == GL_TRUE) {
for (row = 0; row < height; row++, src += row_stride) {
const GLubyte *row_src = src;
GLuint base_x, base_y;
base_x = dPriv->x + px;
base_y = dPriv->y + (dPriv->h - (py + row));
FFBFifo(fmesa, 1);
ffb->fontxy = (base_y << 16) | base_x;
for (col = 0; col < width; col += 32, row_src += 4) {
GLint bitnum, font_w = (width - col);
GLuint font_data;
if (font_w > 32)
font_w = 32;
font_data = 0;
for (bitnum = 0; bitnum < 32; bitnum++) {
const GLubyte val = row_src[bitnum >> 3];
if (val & (1 << (bitnum & (8 - 1))))
font_data |= (1 << (31 - bitnum));
}
FFBFifo(fmesa, 2);
ffb->fontw = font_w;
ffb->font = font_data;
}
}
} else {
for (row = 0; row < height; row++, src += row_stride) {
const GLubyte *row_src = src;
GLuint base_x, base_y;
base_x = dPriv->x + px;
base_y = dPriv->y + (dPriv->h - (py + row));
FFBFifo(fmesa, 1);
ffb->fontxy = (base_y << 16) | base_x;
for (col = 0; col < width; col += 32, row_src += 4) {
GLint font_w = (width - col);
if (font_w > 32)
font_w = 32;
FFBFifo(fmesa, 2);
ffb->fontw = font_w;
ffb->font = (((unsigned int)row_src[0]) << 24 |
((unsigned int)row_src[1]) << 16 |
((unsigned int)row_src[2]) << 8 |
((unsigned int)row_src[3]) << 0);
}
}
}
FFBFifo(fmesa, 1);
ffb->ppc = ppc;
fmesa->ffbScreen->rp_active = 1;
UNLOCK_HARDWARE(fmesa);
fmesa->hw_locked = 0;
}
void ffbDDInitBitmapFuncs(GLcontext *ctx)
{
ctx->Driver.Bitmap = ffb_bitmap;
}