Clean-up and optimize alpha test code.

Major clean-up of pixel zoom code.
This commit is contained in:
Brian Paul 2002-01-31 00:27:43 +00:00
parent e79de014c5
commit ceb39f4f8d
7 changed files with 465 additions and 559 deletions

View file

@ -1,4 +1,4 @@
/* $Id: s_alpha.c,v 1.7 2002/01/28 00:07:33 brianp Exp $ */
/* $Id: s_alpha.c,v 1.8 2002/01/31 00:27:43 brianp Exp $ */
/*
* Mesa 3-D graphics library
@ -32,6 +32,7 @@
#include "mmath.h"
#include "s_alpha.h"
#include "s_context.h"
/*
@ -42,67 +43,174 @@
* 1 = one or more pixels passed the alpha test.
*/
GLint
_mesa_alpha_test( const GLcontext *ctx, struct sw_span *span,
CONST GLchan rgba[][4])
_mesa_alpha_test( const GLcontext *ctx, struct sw_span *span )
{
GLuint i;
const GLchan (*rgba)[4] = (const GLchan (*)[4]) span->color.rgba;
const GLchan ref = ctx->Color.AlphaRef;
const GLuint n = span->end;
GLubyte *mask = span->mask;
GLuint i;
ASSERT(span->arrayMask & SPAN_RGBA);
/* switch cases ordered from most frequent to less frequent */
switch (ctx->Color.AlphaFunc) {
case GL_LESS:
for (i=span->start; i<span->end; i++) {
mask[i] &= (rgba[i][ACOMP] < ref);
}
break;
case GL_LEQUAL:
for (i=span->start; i<span->end; i++)
mask[i] &= (rgba[i][ACOMP] <= ref);
break;
case GL_GEQUAL:
for (i=span->start; i<span->end; i++) {
mask[i] &= (rgba[i][ACOMP] >= ref);
}
break;
case GL_GREATER:
for (i=span->start; i<span->end; i++) {
mask[i] &= (rgba[i][ACOMP] > ref);
}
break;
case GL_NOTEQUAL:
for (i=span->start; i<span->end; i++) {
mask[i] &= (rgba[i][ACOMP] != ref);
}
break;
case GL_EQUAL:
for (i=span->start; i<span->end; i++) {
mask[i] &= (rgba[i][ACOMP] == ref);
}
break;
case GL_ALWAYS:
/* do nothing */
return 1;
case GL_NEVER:
/* caller should check for zero! */
return 0;
default:
_mesa_problem( ctx, "Invalid alpha test in gl_alpha_test" );
return 0;
if (span->arrayMask & SPAN_RGBA) {
/* Use the array values */
switch (ctx->Color.AlphaFunc) {
case GL_LESS:
for (i = 0; i < n; i++)
mask[i] &= (rgba[i][ACOMP] < ref);
break;
case GL_LEQUAL:
for (i = 0; i < n; i++)
mask[i] &= (rgba[i][ACOMP] <= ref);
break;
case GL_GEQUAL:
for (i = 0; i < n; i++)
mask[i] &= (rgba[i][ACOMP] >= ref);
break;
case GL_GREATER:
for (i = 0; i < n; i++)
mask[i] &= (rgba[i][ACOMP] > ref);
break;
case GL_NOTEQUAL:
for (i = 0; i < n; i++)
mask[i] &= (rgba[i][ACOMP] != ref);
break;
case GL_EQUAL:
for (i = 0; i < n; i++)
mask[i] &= (rgba[i][ACOMP] == ref);
break;
case GL_ALWAYS:
/* do nothing */
return 1;
case GL_NEVER:
/* caller should check for zero! */
span->writeAll = GL_FALSE;
return 0;
default:
_mesa_problem( ctx, "Invalid alpha test in _mesa_alpha_test" );
return 0;
}
}
else {
/* Use the interpolation values */
#if CHAN_TYPE == GL_FLOAT
const GLfloat alphaStep = span->alphaStep;
GLfloat alpha = span->alpha;
ASSERT(span->interpMask & SPAN_RGBA);
switch (ctx->Color.AlphaFunc) {
case GL_LESS:
for (i = 0; i < n; i++) {
mask[i] &= (alpha < ref);
alpha += alphaStep;
}
break;
case GL_LEQUAL:
for (i = 0; i < n; i++) {
mask[i] &= (alpha <= ref);
alpha += alphaStep;
}
break;
case GL_GEQUAL:
for (i = 0; i < n; i++) {
mask[i] &= (alpha >= ref);
alpha += alphaStep;
}
break;
case GL_GREATER:
for (i = 0; i < n; i++) {
mask[i] &= (alpha > ref);
alpha += alphaStep;
}
break;
case GL_NOTEQUAL:
for (i = 0; i < n; i++) {
mask[i] &= (alpha != ref);
alpha += alphaStep;
}
break;
case GL_EQUAL:
for (i = 0; i < n; i++) {
mask[i] &= (alpha == ref);
alpha += alphaStep;
}
break;
case GL_ALWAYS:
/* do nothing */
return 1;
case GL_NEVER:
/* caller should check for zero! */
span->writeAll = GL_FALSE;
return 0;
default:
_mesa_problem( ctx, "Invalid alpha test in gl_alpha_test" );
return 0;
}
#else
/* 8 or 16-bit channel interpolation */
const GLfixed alphaStep = span->alphaStep;
GLfixed alpha = span->alpha;
ASSERT(span->interpMask & SPAN_RGBA);
switch (ctx->Color.AlphaFunc) {
case GL_LESS:
for (i = 0; i < n; i++) {
mask[i] &= (FixedToChan(alpha) < ref);
alpha += alphaStep;
}
break;
case GL_LEQUAL:
for (i = 0; i < n; i++) {
mask[i] &= (FixedToChan(alpha) <= ref);
alpha += alphaStep;
}
break;
case GL_GEQUAL:
for (i = 0; i < n; i++) {
mask[i] &= (FixedToChan(alpha) >= ref);
alpha += alphaStep;
}
break;
case GL_GREATER:
for (i = 0; i < n; i++) {
mask[i] &= (FixedToChan(alpha) > ref);
alpha += alphaStep;
}
break;
case GL_NOTEQUAL:
for (i = 0; i < n; i++) {
mask[i] &= (FixedToChan(alpha) != ref);
alpha += alphaStep;
}
break;
case GL_EQUAL:
for (i = 0; i < n; i++) {
mask[i] &= (FixedToChan(alpha) == ref);
alpha += alphaStep;
}
break;
case GL_ALWAYS:
/* do nothing */
return 1;
case GL_NEVER:
/* caller should check for zero! */
span->writeAll = GL_FALSE;
return 0;
default:
_mesa_problem( ctx, "Invalid alpha test in gl_alpha_test" );
return 0;
}
#endif /* CHAN_TYPE */
}
#if 0
/* XXXX This causes conformance failures!!!! */
while ((span->start <= span->end) &&
(mask[span->start] == 0))
(mask[span->start] == 0))
span->start ++;
while ((span->end >= span->start) &&
(mask[span->end] == 0))
(mask[span->end] == 0))
span->end --;
#endif
span->writeAll = GL_FALSE;
if (span->start >= span->end)
@ -122,7 +230,7 @@ _mesa_alpha_test( const GLcontext *ctx, struct sw_span *span,
*/
GLint
_old_alpha_test( const GLcontext *ctx,
GLuint n, CONST GLchan rgba[][4], GLubyte mask[] )
GLuint n, CONST GLchan rgba[][4], GLubyte mask[] )
{
GLuint i;
const GLchan ref = ctx->Color.AlphaRef;

View file

@ -1,10 +1,10 @@
/* $Id: s_alpha.h,v 1.4 2002/01/21 18:12:34 brianp Exp $ */
/* $Id: s_alpha.h,v 1.5 2002/01/31 00:27:43 brianp Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.5
* Version: 4.1
*
* Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -36,9 +36,9 @@
extern GLint
_old_alpha_test( const GLcontext *ctx, GLuint n,
CONST GLchan rgba[][4], GLubyte mask[] );
extern GLint
_mesa_alpha_test( const GLcontext *ctx, struct sw_span *span,
CONST GLchan rgba[][4]);
_mesa_alpha_test( const GLcontext *ctx, struct sw_span *span );
#endif

View file

@ -1,4 +1,4 @@
/* $Id: s_copypix.c,v 1.31 2002/01/28 04:25:56 brianp Exp $ */
/* $Id: s_copypix.c,v 1.32 2002/01/31 00:27:43 brianp Exp $ */
/*
* Mesa 3-D graphics library
@ -272,10 +272,12 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
(const GLchan (*)[4])span.color.rgba, NULL );
}
else if (zoom) {
_mesa_write_zoomed_rgba_span( ctx, width, destx, dy, span.zArray,
span.fogArray,
(const GLchan (*)[4])span.color.rgba,
desty);
span.x = destx;
span.y = dy;
span.end = width;
_mesa_write_zoomed_rgba_span(ctx, &span,
(CONST GLchan (*)[4])span.color.rgba,
desty);
}
else {
span.x = destx;
@ -511,10 +513,12 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
(const GLchan (*)[4])span.color.rgba, NULL );
}
else if (zoom) {
_mesa_write_zoomed_rgba_span( ctx, width, destx, dy, span.zArray,
span.fogArray,
(const GLchan (*)[4]) span.color.rgba,
desty);
span.x = destx;
span.y = dy;
span.end = width;
_mesa_write_zoomed_rgba_span(ctx, &span,
(CONST GLchan (*)[4]) span.color.rgba,
desty);
}
else {
span.x = destx;
@ -629,17 +633,13 @@ static void copy_ci_pixels( GLcontext *ctx,
_mesa_map_ci( ctx, width, span.color.index );
}
if (zoom) {
_mesa_write_zoomed_index_span(ctx, width, destx, dy,
span.zArray, span.fogArray,
span.color.index, desty );
}
else {
span.x = destx;
span.y = dy;
span.end = width;
span.x = destx;
span.y = dy;
span.end = width;
if (zoom)
_mesa_write_zoomed_index_span(ctx, &span, desty);
else
_mesa_write_index_span(ctx, &span, GL_BITMAP);
}
}
/* Restore pixel source to be the draw buffer (for blending, etc) */
@ -729,32 +729,22 @@ static void copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
span.zArray[i] = (GLdepth) (CLAMP(d, 0.0F, 1.0F) * ctx->DepthMax);
}
span.x = destx;
span.y = dy;
span.end = width;
if (ctx->Visual.rgbMode) {
if (zoom) {
_mesa_write_zoomed_rgba_span( ctx, width, destx, dy, span.zArray,
span.fogArray,
if (zoom)
_mesa_write_zoomed_rgba_span( ctx, &span,
(const GLchan (*)[4])span.color.rgba,
desty );
}
else {
span.x = destx;
span.y = dy;
span.end = width;
else
_mesa_write_rgba_span(ctx, &span, GL_BITMAP);
}
}
else {
if (zoom) {
_mesa_write_zoomed_index_span( ctx, width, destx, dy,
span.zArray, span.fogArray,
span.color.index, desty );
}
else {
span.x = destx;
span.y = dy;
span.end = width;
if (zoom)
_mesa_write_zoomed_index_span( ctx, &span, desty );
else
_mesa_write_index_span(ctx, &span, GL_BITMAP);
}
}
}

View file

@ -1,4 +1,4 @@
/* $Id: s_drawpix.c,v 1.27 2002/01/28 00:07:33 brianp Exp $ */
/* $Id: s_drawpix.c,v 1.28 2002/01/31 00:27:43 brianp Exp $ */
/*
* Mesa 3-D graphics library
@ -103,13 +103,20 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const struct gl_pixelstore_attrib *unpack = &ctx->Unpack;
GLchan rgb[MAX_WIDTH][3];
GLchan rgba[MAX_WIDTH][4];
struct sw_span span;
INIT_SPAN(span);
span.arrayMask |= SPAN_RGBA;
if (!ctx->Current.RasterPosValid) {
return GL_TRUE; /* no-op */
}
if (ctx->Depth.Test)
_mesa_span_default_z(ctx, &span);
if (ctx->Fog.Enabled)
_mesa_span_default_fog(ctx, &span);
if ((SWRAST_CONTEXT(ctx)->_RasterMask&(~(SCISSOR_BIT|WINCLIP_BIT)))==0
&& ctx->Texture._ReallyEnabled == 0
&& unpack->Alignment == 1
@ -232,8 +239,11 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
/* with zooming */
GLint row;
for (row=0; row<drawHeight; row++) {
_mesa_write_zoomed_rgba_span(ctx, drawWidth, destX, destY,
zSpan, 0, (CONST GLchan (*)[4]) src, zoomY0);
span.x = destX;
span.y = destY;
span.end = drawWidth;
_mesa_write_zoomed_rgba_span(ctx, &span,
(CONST GLchan (*)[4]) src, zoomY0);
src += rowLength * 4;
destY++;
}
@ -269,8 +279,11 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
/* with zooming */
GLint row;
for (row=0; row<drawHeight; row++) {
_mesa_write_zoomed_rgb_span(ctx, drawWidth, destX, destY,
zSpan, 0, (CONST GLchan (*)[3]) src, zoomY0);
span.x = destX;
span.y = destY;
span.end = drawWidth;
_mesa_write_zoomed_rgb_span(ctx, &span,
(CONST GLchan (*)[3]) src, zoomY0);
src += rowLength * 3;
destY++;
}
@ -290,12 +303,12 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
for (row=0; row<drawHeight; row++) {
GLint i;
for (i=0;i<drawWidth;i++) {
rgb[i][0] = src[i];
rgb[i][1] = src[i];
rgb[i][2] = src[i];
span.color.rgb[i][0] = src[i];
span.color.rgb[i][1] = src[i];
span.color.rgb[i][2] = src[i];
}
(*swrast->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY,
(CONST GLchan (*)[3]) rgb, NULL);
(CONST GLchan (*)[3]) span.color.rgb, NULL);
src += rowLength;
destY++;
}
@ -307,13 +320,13 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
for (row=0; row<drawHeight; row++) {
GLint i;
for (i=0;i<drawWidth;i++) {
rgb[i][0] = src[i];
rgb[i][1] = src[i];
rgb[i][2] = src[i];
span.color.rgb[i][0] = src[i];
span.color.rgb[i][1] = src[i];
span.color.rgb[i][2] = src[i];
}
destY--;
(*swrast->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY,
(CONST GLchan (*)[3]) rgb, NULL);
(CONST GLchan (*)[3]) span.color.rgb, NULL);
src += rowLength;
}
}
@ -324,12 +337,15 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
for (row=0; row<drawHeight; row++) {
GLint i;
for (i=0;i<drawWidth;i++) {
rgb[i][0] = src[i];
rgb[i][1] = src[i];
rgb[i][2] = src[i];
span.color.rgb[i][0] = src[i];
span.color.rgb[i][1] = src[i];
span.color.rgb[i][2] = src[i];
}
_mesa_write_zoomed_rgb_span(ctx, drawWidth, destX, destY,
zSpan, 0, (CONST GLchan (*)[3]) rgb, zoomY0);
span.x = destX;
span.y = destY;
span.end = drawWidth;
_mesa_write_zoomed_rgb_span(ctx, &span,
(CONST GLchan (*)[3]) span.color.rgb, zoomY0);
src += rowLength;
destY++;
}
@ -350,13 +366,13 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
GLint i;
GLchan *ptr = src;
for (i=0;i<drawWidth;i++) {
rgba[i][0] = *ptr;
rgba[i][1] = *ptr;
rgba[i][2] = *ptr++;
rgba[i][3] = *ptr++;
span.color.rgba[i][0] = *ptr;
span.color.rgba[i][1] = *ptr;
span.color.rgba[i][2] = *ptr++;
span.color.rgba[i][3] = *ptr++;
}
(*swrast->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
(CONST GLchan (*)[4]) rgba, NULL);
(CONST GLchan (*)[4]) span.color.rgba, NULL);
src += rowLength*2;
destY++;
}
@ -369,14 +385,14 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
GLint i;
GLchan *ptr = src;
for (i=0;i<drawWidth;i++) {
rgba[i][0] = *ptr;
rgba[i][1] = *ptr;
rgba[i][2] = *ptr++;
rgba[i][3] = *ptr++;
span.color.rgba[i][0] = *ptr;
span.color.rgba[i][1] = *ptr;
span.color.rgba[i][2] = *ptr++;
span.color.rgba[i][3] = *ptr++;
}
destY--;
(*swrast->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
(CONST GLchan (*)[4]) rgba, NULL);
(CONST GLchan (*)[4]) span.color.rgba, NULL);
src += rowLength*2;
}
}
@ -388,13 +404,16 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
GLchan *ptr = src;
GLint i;
for (i=0;i<drawWidth;i++) {
rgba[i][0] = *ptr;
rgba[i][1] = *ptr;
rgba[i][2] = *ptr++;
rgba[i][3] = *ptr++;
span.color.rgba[i][0] = *ptr;
span.color.rgba[i][1] = *ptr;
span.color.rgba[i][2] = *ptr++;
span.color.rgba[i][3] = *ptr++;
}
_mesa_write_zoomed_rgba_span(ctx, drawWidth, destX, destY,
zSpan, 0, (CONST GLchan (*)[4]) rgba, zoomY0);
span.x = destX;
span.y = destY;
span.end = drawWidth;
_mesa_write_zoomed_rgba_span(ctx, &span,
(CONST GLchan (*)[4]) span.color.rgba, zoomY0);
src += rowLength*2;
destY++;
}
@ -411,10 +430,9 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
GLint row;
for (row=0; row<drawHeight; row++) {
ASSERT(drawWidth < MAX_WIDTH);
_mesa_map_ci8_to_rgba(ctx, drawWidth, src, rgba);
_mesa_map_ci8_to_rgba(ctx, drawWidth, src, span.color.rgba);
(*swrast->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
(const GLchan (*)[4]) rgba,
NULL);
(const GLchan (*)[4]) span.color.rgba, NULL);
src += rowLength;
destY++;
}
@ -425,11 +443,10 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
GLint row;
for (row=0; row<drawHeight; row++) {
ASSERT(drawWidth < MAX_WIDTH);
_mesa_map_ci8_to_rgba(ctx, drawWidth, src, rgba);
_mesa_map_ci8_to_rgba(ctx, drawWidth, src, span.color.rgba);
destY--;
(*swrast->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
(CONST GLchan (*)[4]) rgba,
NULL);
(CONST GLchan (*)[4]) span.color.rgba, NULL);
src += rowLength;
}
return GL_TRUE;
@ -439,9 +456,12 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
GLint row;
for (row=0; row<drawHeight; row++) {
ASSERT(drawWidth < MAX_WIDTH);
_mesa_map_ci8_to_rgba(ctx, drawWidth, src, rgba);
_mesa_write_zoomed_rgba_span(ctx, drawWidth, destX, destY,
zSpan, 0, (CONST GLchan (*)[4]) rgba, zoomY0);
_mesa_map_ci8_to_rgba(ctx, drawWidth, src, span.color.rgba);
span.x = destX;
span.y = destY;
span.end = drawWidth;
_mesa_write_zoomed_rgba_span(ctx, &span,
(CONST GLchan (*)[4]) span.color.rgba, zoomY0);
src += rowLength;
destY++;
}
@ -510,17 +530,13 @@ draw_index_pixels( GLcontext *ctx, GLint x, GLint y,
span.color.index,
type, source, &ctx->Unpack,
ctx->_ImageTransferState);
if (zoom) {
_mesa_write_zoomed_index_span(ctx, drawWidth, x, y,
span.zArray, span.fogArray,
span.color.index, desty);
}
else {
span.x = x;
span.y = y;
span.end = drawWidth;
span.x = x;
span.y = y;
span.end = drawWidth;
if (zoom)
_mesa_write_zoomed_index_span(ctx, &span, desty);
else
_mesa_write_index_span(ctx, &span, GL_BITMAP);
}
}
}
@ -674,30 +690,21 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
}
}
span.x = x;
span.y = y;
span.end = drawWidth;
if (ctx->Visual.rgbMode) {
if (zoom) {
_mesa_write_zoomed_rgba_span(ctx, width, x, y, span.zArray, 0,
(const GLchan (*)[4]) span.color.rgba, desty);
}
else {
span.x = x;
span.y = y;
span.end = drawWidth;
if (zoom)
_mesa_write_zoomed_rgba_span(ctx, &span,
(const GLchan (*)[4]) span.color.rgba, desty);
else
_mesa_write_rgba_span(ctx, &span, GL_BITMAP);
}
}
else {
if (zoom) {
_mesa_write_zoomed_index_span(ctx, drawWidth, x, y,
span.zArray, 0,
span.color.index, GL_BITMAP);
}
else {
span.x = x;
span.y = y;
span.end = drawWidth;
if (zoom)
_mesa_write_zoomed_index_span(ctx, &span, desty);
else
_mesa_write_index_span(ctx, &span, GL_BITMAP);
}
}
}
}
@ -826,17 +833,10 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
for (row = 0; row < height; row++, y++) {
const GLvoid *source = _mesa_image_address(unpack,
pixels, width, height, format, type, 0, row, 0);
/* printf("Unpack f=0x%x t=0x%x\n", format, type);*/
_mesa_unpack_chan_color_span(ctx, width, GL_RGBA,
(GLchan *) span.color.rgba,
format, type, source, unpack,
transferOps);
if (0){
int k;
for (k = 0; k < width; k++)
printf("%02x ", span.color.rgba[k][3]);
printf("\n");
}
if ((ctx->Pixel.MinMaxEnabled && ctx->MinMax.Sink) ||
(ctx->Pixel.HistogramEnabled && ctx->Histogram.Sink))
@ -852,8 +852,10 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
(CONST GLchan (*)[4]) span.color.rgba, NULL);
}
else if (zoom) {
_mesa_write_zoomed_rgba_span(ctx, width, x, y, span.zArray,
span.fogArray,
span.x = x;
span.y = y;
span.end = width;
_mesa_write_zoomed_rgba_span(ctx, &span,
(CONST GLchan (*)[4]) span.color.rgba, desty);
}
else {

View file

@ -1,4 +1,4 @@
/* $Id: s_span.c,v 1.27 2002/01/28 04:25:56 brianp Exp $ */
/* $Id: s_span.c,v 1.28 2002/01/31 00:27:43 brianp Exp $ */
/*
* Mesa 3-D graphics library
@ -720,6 +720,7 @@ _mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span,
GLboolean monoColor;
ASSERT((span->interpMask & span->arrayMask) == 0);
ASSERT((span->interpMask | span->arrayMask) & SPAN_RGBA);
MEMSET(span->mask, 1, span->end);
span->writeAll = GL_TRUE;
@ -748,17 +749,9 @@ _mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span,
stipple_polygon_span(ctx, span);
}
/* Now we may need to interpolate the colors */
if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) {
interpolate_colors(ctx, span);
/* clear the bit - this allows the WriteMonoCISpan optimization below */
span->interpMask &= ~SPAN_RGBA;
}
/* Do the alpha test */
if (ctx->Color.AlphaEnabled) {
if (!_mesa_alpha_test(ctx, span,
(const GLchan (*)[4]) span->color.rgba)) {
if (!_mesa_alpha_test(ctx, span)) {
span->interpMask = origInterpMask;
span->arrayMask = origArrayMask;
return;
@ -799,6 +792,13 @@ _mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span,
return;
}
/* Now we may need to interpolate the colors */
if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) {
interpolate_colors(ctx, span);
/* clear the bit - this allows the WriteMonoCISpan optimization below */
span->interpMask &= ~SPAN_RGBA;
}
/* Fog */
/* XXX try to simplify the fog code! */
if (ctx->Fog.Enabled) {
@ -919,11 +919,12 @@ _mesa_write_texture_span( GLcontext *ctx, struct sw_span *span,
const GLuint origArrayMask = span->arrayMask;
ASSERT((span->interpMask & span->arrayMask) == 0);
/* printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__, span->interpMask, span->arrayMask);*/
ASSERT(ctx->Texture._ReallyEnabled);
/*
printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__, span->interpMask, span->arrayMask);
*/
MEMSET(span->mask, 1, span->end);
span->writeAll = GL_TRUE;
@ -964,11 +965,9 @@ _mesa_write_texture_span( GLcontext *ctx, struct sw_span *span,
_swrast_multitexture_fragments( ctx, span );
/* Do the alpha test */
if (!_old_alpha_test(ctx, span->end,
(CONST GLchan (*)[4]) span->color.rgba,
span->mask)) {
if (!_mesa_alpha_test(ctx, span)) {
span->arrayMask = origArrayMask;
return;
return;
}
}

View file

@ -1,4 +1,4 @@
/* $Id: s_zoom.c,v 1.11 2002/01/28 03:42:28 brianp Exp $ */
/* $Id: s_zoom.c,v 1.12 2002/01/31 00:27:43 brianp Exp $ */
/*
* Mesa 3-D graphics library
@ -35,402 +35,222 @@
#include "s_zoom.h"
#ifdef DEBUG
#define SAVE_SPAN(span) struct sw_span tmp_span = (span);
#define RESTORE_SPAN(span) \
{ \
GLint i; \
for (i=tmp_span.start; i<tmp_span.end; i++) { \
if (tmp_span.color.rgba[i][RCOMP] != \
(span).color.rgba[i][RCOMP] || \
tmp_span.color.rgba[i][GCOMP] != \
(span).color.rgba[i][GCOMP] || \
tmp_span.color.rgba[i][BCOMP] != \
(span).color.rgba[i][BCOMP]) { \
fprintf(stderr, "glZoom: Color-span changed in subfunction."); \
} \
if (tmp_span.zArray[i] != (span).zArray[i]) { \
fprintf(stderr, "glZoom: Depth-span changed in subfunction."); \
} \
} \
(span) = tmp_span; \
}
#else /* DEBUG not defined */
#define SAVE_SPAN(span) GLint start = (span).start, end = (span).end;
#define RESTORE_SPAN(span) (span).start = start, (span).end = end; \
(span).writeAll = GL_TRUE;
#endif /* DEBUG */
/*
* Write a span of pixels to the frame buffer while applying a pixel zoom.
* This is only used by glDrawPixels and glCopyPixels.
* Input: n - number of pixels in input row
* x, y - destination of the span
* z - depth values for the span
* red, green, blue, alpha - array of colors
* y0 - location of first row in the image we're drawing.
* Helper function called from _mesa_write_zoomed_rgba/rgb/index_span().
*/
void
_mesa_write_zoomed_rgba_span( GLcontext *ctx,
GLuint n, GLint x, GLint y, const GLdepth z[],
const GLfloat *fog,
CONST GLchan rgba[][4], GLint y0 )
static void
zoom_span( GLcontext *ctx, const struct sw_span *span,
const GLvoid *src, GLint y0, GLenum format )
{
GLint r0, r1, row;
GLint c0, c1, skipCol;
GLint i, j;
const GLint maxwidth = MIN2( ctx->DrawBuffer->Width, MAX_WIDTH );
const GLint maxWidth = MIN2( ctx->DrawBuffer->Width, MAX_WIDTH );
GLchan rgbaSave[MAX_WIDTH][4];
GLuint indexSave[MAX_WIDTH];
struct sw_span zoomed;
const GLchan (*rgba)[4] = (const GLchan (*)[4]) src;
const GLchan (*rgb)[3] = (const GLchan (*)[3]) src;
const GLuint *indexes = (const GLuint *) src;
INIT_SPAN(zoomed);
zoomed.arrayMask |= SPAN_RGBA;
if (format == GL_RGBA || format == GL_RGB) {
zoomed.z = span->z;
zoomed.zStep = span->z;
zoomed.fog = span->fog;
zoomed.fogStep = span->fogStep;
zoomed.interpMask = span->interpMask & ~SPAN_RGBA;
zoomed.arrayMask |= SPAN_RGBA;
}
else if (format == GL_COLOR_INDEX) {
zoomed.z = span->z;
zoomed.zStep = span->z;
zoomed.fog = span->fog;
zoomed.fogStep = span->fogStep;
zoomed.interpMask = span->interpMask & ~SPAN_INDEX;
zoomed.arrayMask |= SPAN_INDEX;
}
/* compute width of output row */
zoomed.end = (GLint) ABSF( n * ctx->Pixel.ZoomX );
if (zoomed.end == 0) {
/*
* Compute which columns to draw: [c0, c1)
*/
c0 = (GLint) span->x;
c1 = (GLint) (span->x + span->end * ctx->Pixel.ZoomX);
if (c0 == c1) {
return;
}
/*here ok or better latter? like it was before */
else if (zoomed.end > maxwidth) {
zoomed.end = maxwidth;
else if (c1 < c0) {
/* swap */
GLint ctmp = c1;
c1 = c0;
c0 = ctmp;
}
if (ctx->Pixel.ZoomX<0.0) {
/* adjust x coordinate for left/right mirroring */
zoomed.x = x - zoomed.end;
if (c0 < 0) {
zoomed.x = 0;
zoomed.start = 0;
zoomed.end = c1;
skipCol = -c0;
}
else
zoomed.x = x;
else {
zoomed.x = c0;
zoomed.start = 0;
zoomed.end = c1 - c0;
skipCol = 0;
}
if (zoomed.end > maxWidth)
zoomed.end = maxWidth;
/* compute which rows to draw */
row = y-y0;
/*
* Compute which rows to draw: [r0, r1)
*/
row = span->y - y0;
r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
if (r0==r1) {
if (r0 == r1) {
return;
}
else if (r1<r0) {
else if (r1 < r0) {
/* swap */
GLint rtmp = r1;
r1 = r0;
r0 = rtmp;
}
/* return early if r0...r1 is above or below window */
if (r0<0 && r1<0) {
/* below window */
ASSERT(r0 < r1);
ASSERT(c0 < c1);
/*
* Trivial clip rejection testing.
*/
if (r1 < 0) /* below window */
return;
}
if (r0>=ctx->DrawBuffer->Height && r1>=ctx->DrawBuffer->Height) {
/* above window */
if (r0 >= ctx->DrawBuffer->Height) /* above window */
return;
}
/* check if left edge is outside window */
if (zoomed.x < 0) {
zoomed.start = -x;
}
/* make sure span isn't too long or short */
/* if (m>maxwidth) {
m = maxwidth;
}*/
if (zoomed.end <= zoomed.start) {
if (c1 < 0) /* left of window */
return;
if (c0 >= ctx->DrawBuffer->Width) /* right of window */
return;
}
ASSERT( zoomed.end <= MAX_WIDTH );
/* zoom the span horizontally */
if (ctx->Pixel.ZoomX==-1.0F) {
/* n==m */
for (j=zoomed.start; j<zoomed.end; j++) {
i = n - j - 1;
COPY_CHAN4(zoomed.color.rgba[j], rgba[i]);
zoomed.zArray[j] = z[i];
if (format == GL_RGBA) {
if (ctx->Pixel.ZoomX == -1.0F) {
/* common case */
for (j = zoomed.start; j < zoomed.end; j++) {
i = span->end - (j + skipCol) - 1;
COPY_CHAN4(zoomed.color.rgba[j], rgba[i]);
}
}
if (fog && ctx->Fog.Enabled) {
for (j=zoomed.start; j<zoomed.end; j++) {
i = n - j - 1;
zoomed.fogArray[j] = fog[i];
}
else {
/* general solution */
const GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
for (j = zoomed.start; j < zoomed.end; j++) {
i = (GLint) ((j + skipCol) * xscale);
if (i < 0)
i = span->end + i - 1;
COPY_CHAN4(zoomed.color.rgba[j], rgba[i]);
}
}
}
else {
const GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
for (j=zoomed.start; j<zoomed.end; j++) {
i = (GLint) (j * xscale);
if (i<0) i = n + i - 1;
COPY_CHAN4(zoomed.color.rgba[j], rgba[i]);
zoomed.zArray[j] = z[i];
else if (format == GL_RGB) {
if (ctx->Pixel.ZoomX == -1.0F) {
/* common case */
for (j = zoomed.start; j < zoomed.end; j++) {
i = span->end - (j + skipCol) - 1;
zoomed.color.rgba[j][0] = rgb[i][0];
zoomed.color.rgba[j][1] = rgb[i][1];
zoomed.color.rgba[j][2] = rgb[i][2];
zoomed.color.rgba[j][3] = CHAN_MAX;
}
}
if (fog && ctx->Fog.Enabled) {
for (j=zoomed.start; j<zoomed.end; j++) {
i = (GLint) (j * xscale);
if (i<0) i = n + i - 1;
zoomed.fogArray[j] = fog[i];
}
else {
/* general solution */
const GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
for (j = zoomed.start; j < zoomed.end; j++) {
i = (GLint) ((j + skipCol) * xscale);
if (i < 0)
i = span->end + i - 1;
zoomed.color.rgba[j][0] = rgb[i][0];
zoomed.color.rgba[j][1] = rgb[i][1];
zoomed.color.rgba[j][2] = rgb[i][2];
zoomed.color.rgba[j][3] = CHAN_MAX;
}
}
}
else if (format == GL_COLOR_INDEX) {
if (ctx->Pixel.ZoomX == -1.0F) {
/* common case */
for (j = zoomed.start; j < zoomed.end; j++) {
i = span->end - (j + skipCol) - 1;
zoomed.color.index[j] = indexes[i];
}
}
else {
/* general solution */
const GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
for (j = zoomed.start; j < zoomed.end; j++) {
i = (GLint) ((j + skipCol) * xscale);
if (i < 0)
i = span->end + i - 1;
zoomed.color.index[j] = indexes[i];
}
}
}
zoomed.arrayMask |= SPAN_Z;
if (fog)
zoomed.arrayMask |= SPAN_FOG;
/* write the span */
for (zoomed.y = r0; zoomed.y < r1; zoomed.y++) {
SAVE_SPAN(zoomed);
ASSERT((zoomed.interpMask & SPAN_RGBA) == 0);
_mesa_write_rgba_span(ctx, &zoomed, GL_BITMAP);
RESTORE_SPAN(zoomed);
/* problem here: "zoomed" can change inside
"_mesa_write_rgba_span". Best solution: make copy "tmpspan"
and give to function, but too slow */
/* write the span in rows [r0, r1) */
if (format == GL_RGBA || format == GL_RGB) {
/* Writing the span may modify the colors, so make a backup now if we're
* going to call _mesa_write_zoomed_span() more than once.
*/
if (r1 - r0 > 1) {
MEMCPY(rgbaSave, zoomed.color.rgba, zoomed.end * 4 * sizeof(GLchan));
}
for (zoomed.y = r0; zoomed.y < r1; zoomed.y++) {
_mesa_write_rgba_span(ctx, &zoomed, GL_BITMAP);
if (r1 - r0 > 1) {
/* restore the colors */
MEMCPY(zoomed.color.rgba, rgbaSave, zoomed.end*4 * sizeof(GLchan));
}
}
}
else if (format == GL_COLOR_INDEX) {
if (r1 - r0 > 1) {
MEMCPY(indexSave, zoomed.color.index, zoomed.end * sizeof(GLuint));
}
for (zoomed.y = r0; zoomed.y < r1; zoomed.y++) {
_mesa_write_index_span(ctx, &zoomed, GL_BITMAP);
if (r1 - r0 > 1) {
/* restore the colors */
MEMCPY(zoomed.color.index, indexSave, zoomed.end * sizeof(GLuint));
}
}
}
}
void
_mesa_write_zoomed_rgba_span( GLcontext *ctx, const struct sw_span *span,
CONST GLchan rgba[][4], GLint y0 )
{
zoom_span(ctx, span, (const GLvoid *) rgba, y0, GL_RGBA);
}
void
_mesa_write_zoomed_rgb_span( GLcontext *ctx,
GLuint n, GLint x, GLint y, const GLdepth z[],
const GLfloat *fog,
_mesa_write_zoomed_rgb_span( GLcontext *ctx, const struct sw_span *span,
CONST GLchan rgb[][3], GLint y0 )
{
GLint m;
GLint r0, r1, row, r;
GLint i, j, skipcol;
GLint maxwidth = MIN2( ctx->DrawBuffer->Width, MAX_WIDTH );
struct sw_span zoomed;
INIT_SPAN(zoomed);
zoomed.arrayMask |= SPAN_RGBA;
if (fog && ctx->Fog.Enabled)
zoomed.arrayMask |= SPAN_FOG;
/* compute width of output row */
m = (GLint) ABSF( n * ctx->Pixel.ZoomX );
if (m==0) {
return;
}
if (ctx->Pixel.ZoomX<0.0) {
/* adjust x coordinate for left/right mirroring */
x = x - m;
}
/* compute which rows to draw */
row = y-y0;
r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
if (r0==r1) {
return;
}
else if (r1<r0) {
GLint rtmp = r1;
r1 = r0;
r0 = rtmp;
}
/* return early if r0...r1 is above or below window */
if (r0<0 && r1<0) {
/* below window */
return;
}
if (r0>=ctx->DrawBuffer->Height && r1>=ctx->DrawBuffer->Height) {
/* above window */
return;
}
/* check if left edge is outside window */
skipcol = 0;
if (x<0) {
skipcol = -x;
m += x;
}
/* make sure span isn't too long or short */
if (m>maxwidth) {
m = maxwidth;
}
else if (m<=0) {
return;
}
ASSERT( m <= MAX_WIDTH );
/* zoom the span horizontally */
if (ctx->Pixel.ZoomX==-1.0F) {
/* n==m */
for (j=0;j<m;j++) {
i = n - (j+skipcol) - 1;
zoomed.color.rgba[j][0] = rgb[i][0];
zoomed.color.rgba[j][1] = rgb[i][1];
zoomed.color.rgba[j][2] = rgb[i][2];
zoomed.color.rgba[j][3] = CHAN_MAX;
zoomed.zArray[j] = z[i];
}
if (zoomed.arrayMask & SPAN_FOG) {
for (j=0;j<m;j++) {
i = n - (j+skipcol) - 1;
zoomed.fogArray[j] = fog[i];
}
}
}
else {
GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
for (j=0;j<m;j++) {
i = (GLint) ((j+skipcol) * xscale);
if (i<0) i = n + i - 1;
zoomed.color.rgba[j][0] = rgb[i][0];
zoomed.color.rgba[j][1] = rgb[i][1];
zoomed.color.rgba[j][2] = rgb[i][2];
zoomed.color.rgba[j][3] = CHAN_MAX;
zoomed.zArray[j] = z[i];
}
if (zoomed.arrayMask & SPAN_FOG) {
for (j=0;j<m;j++) {
i = (GLint) ((j+skipcol) * xscale);
if (i<0) i = n + i - 1;
zoomed.fogArray[j] = fog[i];
}
}
}
/* write the span */
for (r=r0; r<r1; r++) {
zoomed.x = x + skipcol;
zoomed.y = r;
zoomed.end = m;
ASSERT((zoomed.interpMask & SPAN_RGBA) == 0);
_mesa_write_rgba_span( ctx, &zoomed, GL_BITMAP );
}
zoom_span(ctx, span, (const GLvoid *) rgb, y0, GL_RGB);
}
/*
* As above, but write CI pixels.
*/
void
_mesa_write_zoomed_index_span( GLcontext *ctx,
GLuint n, GLint x, GLint y, const GLdepth z[],
const GLfloat *fog,
const GLuint indexes[], GLint y0 )
_mesa_write_zoomed_index_span( GLcontext *ctx, const struct sw_span *span,
GLint y0 )
{
GLint m;
GLint r0, r1, row, r;
GLint i, j, skipcol;
GLint maxwidth = MIN2( ctx->DrawBuffer->Width, MAX_WIDTH );
struct sw_span zoomed;
INIT_SPAN(zoomed);
zoomed.arrayMask |= SPAN_INDEX;
/* compute width of output row */
m = (GLint) ABSF( n * ctx->Pixel.ZoomX );
if (m==0) {
return;
}
if (ctx->Pixel.ZoomX<0.0) {
/* adjust x coordinate for left/right mirroring */
x = x - m;
}
/* compute which rows to draw */
row = y-y0;
r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
if (r0==r1) {
return;
}
else if (r1<r0) {
GLint rtmp = r1;
r1 = r0;
r0 = rtmp;
}
/* return early if r0...r1 is above or below window */
if (r0<0 && r1<0) {
/* below window */
return;
}
if (r0>=ctx->DrawBuffer->Height && r1>=ctx->DrawBuffer->Height) {
/* above window */
return;
}
/* check if left edge is outside window */
skipcol = 0;
if (x<0) {
skipcol = -x;
m += x;
}
/* make sure span isn't too long or short */
if (m>maxwidth) {
m = maxwidth;
}
else if (m<=0) {
return;
}
ASSERT( m <= MAX_WIDTH );
/* zoom the span horizontally */
if (ctx->Pixel.ZoomX==-1.0F) {
/* n==m */
for (j=0;j<m;j++) {
i = n - (j+skipcol) - 1;
zoomed.color.index[j] = indexes[i];
zoomed.zArray[j] = z[i];
}
if (fog && ctx->Fog.Enabled) {
for (j=0;j<m;j++) {
i = n - (j+skipcol) - 1;
zoomed.fogArray[j] = fog[i];
}
zoomed.arrayMask |= SPAN_FOG;
}
}
else {
GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
for (j=0;j<m;j++) {
i = (GLint) ((j+skipcol) * xscale);
if (i<0) i = n + i - 1;
zoomed.color.index[j] = indexes[i];
zoomed.zArray[j] = z[i];
}
if (fog && ctx->Fog.Enabled) {
for (j=0;j<m;j++) {
i = (GLint) ((j+skipcol) * xscale);
if (i<0) i = n + i - 1;
zoomed.fogArray[j] = fog[i];
}
zoomed.arrayMask |= SPAN_FOG;
}
}
zoomed.arrayMask |= SPAN_Z;
/* write the span */
for (r=r0; r<r1; r++) {
SAVE_SPAN(zoomed);
ASSERT((zoomed.interpMask & SPAN_INDEX) == 0);
zoomed.x = x + skipcol;
zoomed.y = r;
zoomed.end = m;
_mesa_write_index_span(ctx, &zoomed, GL_BITMAP);
RESTORE_SPAN(zoomed);
}
zoom_span(ctx, span, (const GLvoid *) span->color.index, y0, GL_COLOR_INDEX);
}
/*
* As above, but write stencil values.
*/

View file

@ -1,4 +1,4 @@
/* $Id: s_zoom.h,v 1.6 2002/01/21 18:12:34 brianp Exp $ */
/* $Id: s_zoom.h,v 1.7 2002/01/31 00:27:43 brianp Exp $ */
/*
* Mesa 3-D graphics library
@ -24,39 +24,26 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef S_ZOOM_H
#define S_ZOOM_H
#include "mtypes.h"
#include "swrast.h"
extern void
_mesa_write_zoomed_rgba_span( GLcontext *ctx,
GLuint n, GLint x, GLint y, const GLdepth z[],
const GLfloat *fog,
CONST GLchan rgba[][4], GLint y0 );
_mesa_write_zoomed_rgba_span( GLcontext *ctx, const struct sw_span *span,
CONST GLchan rgb[][4], GLint y0 );
extern void
_mesa_write_zoomed_rgb_span( GLcontext *ctx,
GLuint n, GLint x, GLint y, const GLdepth z[],
const GLfloat *fog,
_mesa_write_zoomed_rgb_span( GLcontext *ctx, const struct sw_span *span,
CONST GLchan rgb[][3], GLint y0 );
extern void
_mesa_write_zoomed_index_span( GLcontext *ctx, const struct sw_span *span,
GLint y0 );
extern void
_mesa_write_zoomed_index_span( GLcontext *ctx,
GLuint n, GLint x, GLint y, const GLdepth z[],
const GLfloat *fog,
const GLuint indexes[], GLint y0 );
extern void
_mesa_write_zoomed_stencil_span( GLcontext *ctx,
GLuint n, GLint x, GLint y,
_mesa_write_zoomed_stencil_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
const GLstencil stencil[], GLint y0 );
#endif