X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fswrast%2Fs_zoom.c;h=6cc9be587c4556f9779a6417249f3428e7d805d3;hb=d0492cf1377897c8113a109aa936ee7a7084b9c8;hp=daace6920fd2fdca36135cf4e1a877cc6cff44ee;hpb=22144ab7552f0799bcfca506bf4ffa7f70a06649;p=mesa.git diff --git a/src/mesa/swrast/s_zoom.c b/src/mesa/swrast/s_zoom.c index daace6920fd..6cc9be587c4 100644 --- a/src/mesa/swrast/s_zoom.c +++ b/src/mesa/swrast/s_zoom.c @@ -1,10 +1,10 @@ -/* $Id: s_zoom.c,v 1.4 2001/03/12 00:48:42 gareth Exp $ */ +/* $Id: s_zoom.c,v 1.24 2003/03/25 02:23:48 brianp Exp $ */ /* * Mesa 3-D graphics library - * Version: 3.5 + * Version: 5.1 * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2003 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"), @@ -26,6 +26,8 @@ #include "glheader.h" #include "macros.h" +#include "imports.h" +#include "colormac.h" #include "s_context.h" #include "s_span.h" @@ -33,347 +35,258 @@ #include "s_zoom.h" - /* - * 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 _swrast_write_zoomed_rgba/rgb/index_span(). */ -void -_mesa_write_zoomed_rgba_span( GLcontext *ctx, - GLuint n, GLint x, GLint y, const GLdepth z[], - const GLfixed *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 skipPixels ) { - GLint m; - GLint r0, r1, row, r; - GLint i, j, skipcol; - GLchan zrgba[MAX_WIDTH][4]; /* zoomed pixel colors */ - GLdepth zdepth[MAX_WIDTH]; /* zoomed depth values */ - GLfixed zfog[MAX_WIDTH]; /* zoomed fog values */ - GLint maxwidth = MIN2( ctx->DrawBuffer->Width, MAX_WIDTH ); - const GLuint *srcRGBA32 = (const GLuint *) rgba; - GLuint *dstRGBA32 = (GLuint *) zrgba; - - /* compute width of output row */ - m = (GLint) ABSF( n * ctx->Pixel.ZoomX ); - if (m==0) { + GLint r0, r1, row; + GLint c0, c1, skipCol; + GLint i, j; + const GLuint maxWidth = MIN2( ctx->DrawBuffer->Width, MAX_WIDTH ); + GLchan rgbaSave[MAX_WIDTH][4]; + GLuint indexSave[MAX_WIDTH]; + const GLchan (*rgba)[4] = (const GLchan (*)[4]) src; + const GLchan (*rgb)[3] = (const GLchan (*)[3]) src; + const GLuint *indexes = (const GLuint *) src; + struct sw_span zoomed; + struct span_arrays zoomed_arrays; /* this is big! */ + + /* no pixel arrays! */ + ASSERT((span->arrayMask & SPAN_XY) == 0); + ASSERT(span->primitive == GL_BITMAP); + + INIT_SPAN(zoomed, GL_BITMAP, 0, 0, 0); + zoomed.array = &zoomed_arrays; + + zoomed.z = span->z; + zoomed.zStep = span->zStep; /* span->zStep == 0 */ + zoomed.fog = span->fog; + zoomed.fogStep = span->fogStep; + if (format == GL_RGBA || format == GL_RGB) { + zoomed.interpMask = span->interpMask & ~SPAN_RGBA; + zoomed.arrayMask |= SPAN_RGBA; + } + else if (format == GL_COLOR_INDEX) { + zoomed.interpMask = span->interpMask & ~SPAN_INDEX; + zoomed.arrayMask |= SPAN_INDEX; + } + + /* + * Compute which columns to draw: [c0, c1) + */ +#if 0 + c0 = (GLint) span->x; + c1 = (GLint) (span->x + span->end * ctx->Pixel.ZoomX); +#else + c0 = (GLint) (span->x + skipPixels * ctx->Pixel.ZoomX); + c1 = (GLint) (span->x + (skipPixels + span->end) * ctx->Pixel.ZoomX); +#endif + if (c0 == c1) { return; } - if (ctx->Pixel.ZoomX<0.0) { - /* adjust x coordinate for left/right mirroring */ - x = x - m; + else if (c1 < c0) { + /* swap */ + GLint ctmp = c1; + c1 = c0; + c0 = ctmp; } - - /* compute which rows to draw */ - row = y-y0; + if (c0 < 0) { + zoomed.x = 0; + zoomed.start = 0; + zoomed.end = c1; + skipCol = -c0; + } + 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: [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=ctx->DrawBuffer->Height && r1>=ctx->DrawBuffer->Height) { - /* above window */ + if (r0 >= (GLint) 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) { + if (c1 < 0) /* left of window */ + return; + if (c0 >= (GLint) ctx->DrawBuffer->Width) /* right of window */ return; - } - - assert( m <= MAX_WIDTH ); /* zoom the span horizontally */ - if (ctx->Pixel.ZoomX==-1.0F) { - /* n==m */ - for (j=0;jPixel.ZoomX == -1.0F) { + /* common case */ + for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) { + i = span->end - (j + skipCol) - 1; + COPY_CHAN4(zoomed.array->rgba[j], rgba[i]); + } } - if (fog && ctx->Fog.Enabled) { - for (j=0;jPixel.ZoomX; + for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) { + i = (GLint) ((j + skipCol) * xscale); + if (ctx->Pixel.ZoomX < 0.0) { + ASSERT(i <= 0); + i = span->end + i - 1; + } + ASSERT(i >= 0); + ASSERT(i < (GLint) span->end); + COPY_CHAN4(zoomed.array->rgba[j], rgba[i]); + } } } - else { - GLfloat xscale = 1.0F / ctx->Pixel.ZoomX; - for (j=0;jPixel.ZoomX == -1.0F) { + /* common case */ + for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) { + i = span->end - (j + skipCol) - 1; + zoomed.array->rgba[j][0] = rgb[i][0]; + zoomed.array->rgba[j][1] = rgb[i][1]; + zoomed.array->rgba[j][2] = rgb[i][2]; + zoomed.array->rgba[j][3] = CHAN_MAX; + } } - if (fog && ctx->Fog.Enabled) { - for (j=0;jPixel.ZoomX; + for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) { + i = (GLint) ((j + skipCol) * xscale); + if (ctx->Pixel.ZoomX < 0.0) { + ASSERT(i <= 0); + i = span->end + i - 1; + } + ASSERT(i >= 0); + ASSERT(i < (GLint) span->end); + zoomed.array->rgba[j][0] = rgb[i][0]; + zoomed.array->rgba[j][1] = rgb[i][1]; + zoomed.array->rgba[j][2] = rgb[i][2]; + zoomed.array->rgba[j][3] = CHAN_MAX; + } } } - - /* write the span */ - for (r=r0; rDrawBuffer->Width, MAX_WIDTH ); - - /* 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=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; + else if (format == GL_COLOR_INDEX) { + if (ctx->Pixel.ZoomX == -1.0F) { + /* common case */ + for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) { + i = span->end - (j + skipCol) - 1; + zoomed.array->index[j] = indexes[i]; + } + } + else { + /* general solution */ + const GLfloat xscale = 1.0F / ctx->Pixel.ZoomX; + for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) { + i = (GLint) ((j + skipCol) * xscale); + if (ctx->Pixel.ZoomX < 0.0) { + ASSERT(i <= 0); + i = span->end + i - 1; + } + ASSERT(i >= 0); + ASSERT(i < (GLint) span->end); + zoomed.array->index[j] = indexes[i]; + } + } } - assert( m <= MAX_WIDTH ); - - /* zoom the span horizontally */ - if (ctx->Pixel.ZoomX==-1.0F) { - /* n==m */ - for (j=0;j 1) { + MEMCPY(rgbaSave, zoomed.array->rgba, zoomed.end * 4 * sizeof(GLchan)); } - if (fog && ctx->Fog.Enabled) { - for (j=0;j 1) { + /* restore the colors */ + MEMCPY(zoomed.array->rgba, rgbaSave, zoomed.end*4 * sizeof(GLchan)); + } } } - else { - GLfloat xscale = 1.0F / ctx->Pixel.ZoomX; - for (j=0;j 1) { + MEMCPY(indexSave, zoomed.array->index, zoomed.end * sizeof(GLuint)); } - if (fog && ctx->Fog.Enabled) { - for (j=0;j 1) { + /* restore the colors */ + MEMCPY(zoomed.array->index, indexSave, zoomed.end * sizeof(GLuint)); + } } } - - /* write the span */ - for (r=r0; rDrawBuffer->Width, MAX_WIDTH ); - - /* 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=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 ); +void +_swrast_write_zoomed_rgb_span( GLcontext *ctx, const struct sw_span *span, + CONST GLchan rgb[][3], GLint y0, + GLint skipPixels ) +{ + zoom_span(ctx, span, (const GLvoid *) rgb, y0, GL_RGB, skipPixels); +} - /* zoom the span horizontally */ - if (ctx->Pixel.ZoomX==-1.0F) { - /* n==m */ - for (j=0;jFog.Enabled) { - for (j=0;jPixel.ZoomX; - for (j=0;jFog.Enabled) { - for (j=0;jarray->index, y0, + GL_COLOR_INDEX, skipPixels); } - /* * As above, but write stencil values. */ void -_mesa_write_zoomed_stencil_span( GLcontext *ctx, +_swrast_write_zoomed_stencil_span( GLcontext *ctx, GLuint n, GLint x, GLint y, - const GLstencil stencil[], GLint y0 ) + const GLstencil stencil[], GLint y0, + GLint skipPixels ) { GLint m; GLint r0, r1, row, r; @@ -381,8 +294,10 @@ _mesa_write_zoomed_stencil_span( GLcontext *ctx, GLstencil zstencil[MAX_WIDTH]; /* zoomed stencil values */ GLint maxwidth = MIN2( ctx->DrawBuffer->Width, MAX_WIDTH ); + (void) skipPixels; /* XXX this shouldn't be ignored */ + /* compute width of output row */ - m = (GLint) ABSF( n * ctx->Pixel.ZoomX ); + m = (GLint) FABSF( n * ctx->Pixel.ZoomX ); if (m==0) { return; } @@ -392,7 +307,7 @@ _mesa_write_zoomed_stencil_span( GLcontext *ctx, } /* compute which rows to draw */ - row = y-y0; + row = y - y0; r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY); r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY); if (r0==r1) { @@ -409,7 +324,8 @@ _mesa_write_zoomed_stencil_span( GLcontext *ctx, /* below window */ return; } - if (r0>=ctx->DrawBuffer->Height && r1>=ctx->DrawBuffer->Height) { + if (r0 >= (GLint) ctx->DrawBuffer->Height && + r1 >= (GLint) ctx->DrawBuffer->Height) { /* above window */ return; } @@ -428,7 +344,7 @@ _mesa_write_zoomed_stencil_span( GLcontext *ctx, return; } - assert( m <= MAX_WIDTH ); + ASSERT( m <= MAX_WIDTH ); /* zoom the span horizontally */ if (ctx->Pixel.ZoomX==-1.0F) { @@ -449,6 +365,6 @@ _mesa_write_zoomed_stencil_span( GLcontext *ctx, /* write the span */ for (r=r0; r