X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fswrast%2Fs_copypix.c;h=0692adfbff96916d199f323a36c7619e1803a3b1;hb=a60c89e8c8348a348dcdd770a033f4976ea93206;hp=ab8198945ce992ed48b01447fc8d7797c6879faa;hpb=acc722d4b890da7ed0ede24751e2bcaf28cc1468;p=mesa.git diff --git a/src/mesa/swrast/s_copypix.c b/src/mesa/swrast/s_copypix.c index ab8198945ce..0692adfbff9 100644 --- a/src/mesa/swrast/s_copypix.c +++ b/src/mesa/swrast/s_copypix.c @@ -1,10 +1,8 @@ -/* $Id: s_copypix.c,v 1.21 2001/06/26 21:15:36 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,19 +24,15 @@ #include "glheader.h" -#include "colormac.h" #include "context.h" #include "convolve.h" -#include "feedback.h" +#include "histogram.h" #include "macros.h" -#include "mem.h" -#include "mmath.h" +#include "imports.h" #include "pixel.h" #include "s_context.h" #include "s_depth.h" -#include "s_fog.h" -#include "s_histogram.h" #include "s_pixeltex.h" #include "s_span.h" #include "s_stencil.h" @@ -67,6 +61,9 @@ regions_overlap(GLint srcx, GLint srcy, else if (srcy < dsty) { /* this is OK */ return GL_FALSE; } + else if (srcy > dsty + height) { + return GL_FALSE; + } else { return GL_TRUE; } @@ -98,37 +95,26 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, GLint width, GLint height, GLint destx, GLint desty) { SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLdepth zspan[MAX_WIDTH]; - GLfloat fogSpan[MAX_WIDTH]; GLboolean quick_draw; GLint row; GLboolean changeBuffer; - GLchan *saveReadAlpha; const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F; const GLuint transferOps = ctx->_ImageTransferState; GLfloat *dest, *tmpImage, *convImage; + struct sw_span span; - if (ctx->Depth.Test || ctx->Fog.Enabled) { - /* fill in array of z values */ - GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->DepthMax); - GLfloat fog; - GLint i; + INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA); - if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) - fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterFogCoord); - else - fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance); + if (ctx->Depth.Test) + _swrast_span_default_z(ctx, &span); + if (ctx->Fog.Enabled) + _swrast_span_default_fog(ctx, &span); - for (i = 0; i < width; i++) { - zspan[i] = z; - fogSpan[i] = fog; - } - } if (SWRAST_CONTEXT(ctx)->_RasterMask == 0 && !zoom && destx >= 0 - && destx + width <= ctx->DrawBuffer->Width) { + && destx + width <= (GLint) ctx->DrawBuffer->Width) { quick_draw = GL_TRUE; } else { @@ -136,7 +122,6 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, } /* If read and draw buffer are different we must do buffer switching */ - saveReadAlpha = ctx->ReadBuffer->Alpha; changeBuffer = ctx->Pixel.ReadBuffer != ctx->Color.DrawBuffer || ctx->DrawBuffer != ctx->ReadBuffer; @@ -157,16 +142,8 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, dest = tmpImage; if (changeBuffer) { - (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, - ctx->Pixel.DriverReadBuffer ); - if (ctx->Pixel.DriverReadBuffer == GL_FRONT_LEFT) - ctx->ReadBuffer->Alpha = ctx->ReadBuffer->FrontLeftAlpha; - else if (ctx->Pixel.DriverReadBuffer == GL_BACK_LEFT) - ctx->ReadBuffer->Alpha = ctx->ReadBuffer->BackLeftAlpha; - else if (ctx->Pixel.DriverReadBuffer == GL_FRONT_RIGHT) - ctx->ReadBuffer->Alpha = ctx->ReadBuffer->FrontRightAlpha; - else - ctx->ReadBuffer->Alpha = ctx->ReadBuffer->BackRightAlpha; + /* choose the read buffer */ + _swrast_use_read_buffer(ctx); } /* read source image */ @@ -174,7 +151,7 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, for (row = 0; row < height; row++) { GLchan rgba[MAX_WIDTH][4]; GLint i; - _mesa_read_rgba_span(ctx, ctx->ReadBuffer, width, srcx, srcy + row, rgba); + _swrast_read_rgba_span(ctx, ctx->ReadBuffer, width, srcx, srcy + row, rgba); /* convert GLchan to GLfloat */ for (i = 0; i < width; i++) { *dest++ = (GLfloat) rgba[i][RCOMP] * (1.0F / CHAN_MAXF); @@ -184,16 +161,14 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, } } - /* read from the draw buffer again (in case of blending) */ if (changeBuffer) { - (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, - ctx->Color.DriverDrawBuffer ); - ctx->ReadBuffer->Alpha = saveReadAlpha; + /* restore default src/dst buffer */ + _swrast_use_draw_buffer(ctx); } /* do image transfer ops up until convolution */ for (row = 0; row < height; row++) { - GLfloat (*rgba)[4] = (GLfloat (*)[4]) tmpImage + row * width * 4; + GLfloat (*rgba)[4] = (GLfloat (*)[4]) (tmpImage + row * width * 4); /* scale & bias */ if (transferOps & IMAGE_SCALE_BIAS_BIT) { @@ -225,7 +200,7 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, /* do remaining image transfer ops */ for (row = 0; row < height; row++) { - GLfloat (*rgba)[4] = (GLfloat (*)[4]) convImage + row * width * 4; + GLfloat (*rgba)[4] = (GLfloat (*)[4]) (convImage + row * width * 4); /* GL_POST_CONVOLUTION_COLOR_TABLE lookup */ if (transferOps & IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT) { @@ -251,7 +226,6 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, for (row = 0; row < height; row++) { const GLfloat *src = convImage + row * width * 4; - GLchan rgba[MAX_WIDTH][4]; GLint i, dy; /* clamp to [0,1] and convert float back to chan */ @@ -260,43 +234,37 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, GLint g = (GLint) (src[i * 4 + GCOMP] * CHAN_MAXF); GLint b = (GLint) (src[i * 4 + BCOMP] * CHAN_MAXF); GLint a = (GLint) (src[i * 4 + ACOMP] * CHAN_MAXF); - rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX); - rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX); - rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX); - rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX); - } - - if (ctx->Texture._ReallyEnabled && ctx->Pixel.PixelTextureEnabled) { - GLfloat s[MAX_WIDTH], t[MAX_WIDTH], r[MAX_WIDTH], q[MAX_WIDTH]; - GLchan primary_rgba[MAX_WIDTH][4]; - GLuint unit; - /* XXX not sure how multitexture is supposed to work here */ - - MEMCPY(primary_rgba, rgba, 4 * width * sizeof(GLchan)); - - for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { - _mesa_pixeltexgen(ctx, width, (const GLchan (*)[4]) rgba, - s, t, r, q); - _swrast_texture_fragments(ctx, unit, width, s, t, r, NULL, - (CONST GLchan (*)[4]) primary_rgba, - rgba); - } + span.array->rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX); + span.array->rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX); + span.array->rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX); + span.array->rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX); + } + + if (ctx->Pixel.PixelTextureEnabled && ctx->Texture._EnabledUnits) { + span.end = width; + _swrast_pixel_texture(ctx, &span); } /* write row to framebuffer */ dy = desty + row; - if (quick_draw && dy >= 0 && dy < ctx->DrawBuffer->Height) { + if (quick_draw && dy >= 0 && dy < (GLint) ctx->DrawBuffer->Height) { (*swrast->Driver.WriteRGBASpan)( ctx, width, destx, dy, - (const GLchan (*)[4])rgba, NULL ); + (const GLchan (*)[4])span.array->rgba, NULL ); } else if (zoom) { - _mesa_write_zoomed_rgba_span( ctx, width, destx, dy, zspan, fogSpan, - (const GLchan (*)[4])rgba, desty); + span.x = destx; + span.y = dy; + span.end = width; + _swrast_write_zoomed_rgba_span(ctx, &span, + (CONST GLchan (*)[4])span.array->rgba, + desty, 0); } else { - _mesa_write_rgba_span( ctx, width, destx, dy, zspan, fogSpan, rgba, - NULL, GL_BITMAP ); + span.x = destx; + span.y = dy; + span.end = width; + _swrast_write_rgba_span(ctx, &span); } } @@ -312,18 +280,16 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, GLint width, GLint height, GLint destx, GLint desty) { SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLdepth zspan[MAX_WIDTH]; - GLfloat fogSpan[MAX_WIDTH]; - GLchan rgba[MAX_WIDTH][4]; GLchan *tmpImage,*p; GLboolean quick_draw; - GLint sy, dy, stepy; - GLint i, j; + GLint sy, dy, stepy, j; GLboolean changeBuffer; - GLchan *saveReadAlpha; const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F; GLint overlapping; const GLuint transferOps = ctx->_ImageTransferState; + struct sw_span span; + + INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA); if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) { copy_conv_rgba_pixels(ctx, srcx, srcy, width, height, destx, desty); @@ -344,29 +310,23 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, stepy = 1; } - overlapping = regions_overlap(srcx, srcy, destx, desty, width, height, - ctx->Pixel.ZoomX, ctx->Pixel.ZoomY); - - if (ctx->Depth.Test || ctx->Fog.Enabled) { - /* fill in array of z values */ - GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->DepthMax); - GLfloat fog; - - if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) - fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterFogCoord); - else - fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance); - - for (i=0;iDrawBuffer == ctx->ReadBuffer) { + overlapping = regions_overlap(srcx, srcy, destx, desty, width, height, + ctx->Pixel.ZoomX, ctx->Pixel.ZoomY); + } + else { + overlapping = GL_FALSE; } + if (ctx->Depth.Test) + _swrast_span_default_z(ctx, &span); + if (ctx->Fog.Enabled) + _swrast_span_default_fog(ctx, &span); + if (SWRAST_CONTEXT(ctx)->_RasterMask == 0 && !zoom && destx >= 0 - && destx + width <= ctx->DrawBuffer->Width) { + && destx + width <= (GLint) ctx->DrawBuffer->Width) { quick_draw = GL_TRUE; } else { @@ -374,13 +334,9 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, } /* If read and draw buffer are different we must do buffer switching */ - saveReadAlpha = ctx->ReadBuffer->Alpha; changeBuffer = ctx->Pixel.ReadBuffer != ctx->Color.DrawBuffer || ctx->DrawBuffer != ctx->ReadBuffer; - (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, - ctx->Pixel.DriverReadBuffer ); - if (overlapping) { GLint ssy = sy; tmpImage = (GLchan *) MALLOC(width * height * sizeof(GLchan) * 4); @@ -388,25 +344,22 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" ); return; } + /* setup source */ + if (changeBuffer) + _swrast_use_read_buffer(ctx); + /* read the source image */ p = tmpImage; - if (changeBuffer) { - (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, - ctx->Pixel.DriverReadBuffer ); - if (ctx->Pixel.DriverReadBuffer == GL_FRONT_LEFT) - ctx->ReadBuffer->Alpha = ctx->ReadBuffer->FrontLeftAlpha; - else if (ctx->Pixel.DriverReadBuffer == GL_BACK_LEFT) - ctx->ReadBuffer->Alpha = ctx->ReadBuffer->BackLeftAlpha; - else if (ctx->Pixel.DriverReadBuffer == GL_FRONT_RIGHT) - ctx->ReadBuffer->Alpha = ctx->ReadBuffer->FrontRightAlpha; - else - ctx->ReadBuffer->Alpha = ctx->ReadBuffer->BackRightAlpha; - } for (j = 0; j < height; j++, ssy += stepy) { - _mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, srcx, ssy, + _swrast_read_rgba_span( ctx, ctx->ReadBuffer, width, srcx, ssy, (GLchan (*)[4]) p ); - p += (width * sizeof(GLchan) * 4); + p += width * 4; } p = tmpImage; + /* restore dest */ + if (changeBuffer) { + _swrast_use_draw_buffer(ctx); + changeBuffer = GL_FALSE; + } } else { tmpImage = NULL; /* silence compiler warnings */ @@ -417,35 +370,19 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, /* Get source pixels */ if (overlapping) { /* get from buffered image */ - MEMCPY(rgba, p, width * sizeof(GLchan) * 4); - p += (width * sizeof(GLchan) * 4); + ASSERT(width < MAX_WIDTH); + MEMCPY(span.array->rgba, p, width * sizeof(GLchan) * 4); + p += width * 4; } else { /* get from framebuffer */ - if (changeBuffer) { - (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, - ctx->Pixel.DriverReadBuffer ); - if (ctx->Pixel.DriverReadBuffer == GL_FRONT_LEFT) { - ctx->ReadBuffer->Alpha = ctx->ReadBuffer->FrontLeftAlpha; - } - else if (ctx->Pixel.DriverReadBuffer == GL_BACK_LEFT) { - ctx->ReadBuffer->Alpha = ctx->ReadBuffer->BackLeftAlpha; - } - else if (ctx->Pixel.DriverReadBuffer == GL_FRONT_RIGHT) { - ctx->ReadBuffer->Alpha = ctx->ReadBuffer->FrontRightAlpha; - } - else { - ctx->ReadBuffer->Alpha = ctx->ReadBuffer->BackRightAlpha; - } - } - _mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, srcx, sy, rgba ); - } - - if (changeBuffer) { - /* read from the draw buffer again (in case of blending) */ - (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, - ctx->Color.DriverDrawBuffer ); - ctx->ReadBuffer->Alpha = saveReadAlpha; + if (changeBuffer) + _swrast_use_read_buffer(ctx); + ASSERT(width < MAX_WIDTH); + _swrast_read_rgba_span( ctx, ctx->ReadBuffer, width, srcx, sy, + span.array->rgba ); + if (changeBuffer) + _swrast_use_draw_buffer(ctx); } if (transferOps) { @@ -456,10 +393,10 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, /* convert chan to float */ for (k = 0; k < width; k++) { - rgbaFloat[k][RCOMP] = (GLfloat) rgba[k][RCOMP] * scale; - rgbaFloat[k][GCOMP] = (GLfloat) rgba[k][GCOMP] * scale; - rgbaFloat[k][BCOMP] = (GLfloat) rgba[k][BCOMP] * scale; - rgbaFloat[k][ACOMP] = (GLfloat) rgba[k][ACOMP] * scale; + rgbaFloat[k][RCOMP] = (GLfloat) span.array->rgba[k][RCOMP] * scale; + rgbaFloat[k][GCOMP] = (GLfloat) span.array->rgba[k][GCOMP] * scale; + rgbaFloat[k][BCOMP] = (GLfloat) span.array->rgba[k][BCOMP] * scale; + rgbaFloat[k][ACOMP] = (GLfloat) span.array->rgba[k][ACOMP] * scale; } /* scale & bias */ if (transferOps & IMAGE_SCALE_BIAS_BIT) { @@ -479,7 +416,8 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, } /* convolution */ if (transferOps & IMAGE_CONVOLUTION_BIT) { - /* XXX to do */ + _mesa_problem(ctx, "Convolution should not be enabled in copy_rgba_pixels()"); + return; } /* GL_POST_CONVOLUTION_RED/GREEN/BLUE/ALPHA_SCALE/BIAS */ if (transferOps & IMAGE_POST_CONVOLUTION_SCALE_BIAS) { @@ -519,80 +457,60 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, GLint g = (GLint) (rgbaFloat[k][GCOMP] * CHAN_MAXF); GLint b = (GLint) (rgbaFloat[k][BCOMP] * CHAN_MAXF); GLint a = (GLint) (rgbaFloat[k][ACOMP] * CHAN_MAXF); - rgba[k][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX); - rgba[k][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX); - rgba[k][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX); - rgba[k][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX); + span.array->rgba[k][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX); + span.array->rgba[k][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX); + span.array->rgba[k][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX); + span.array->rgba[k][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX); } UNDEFARRAY(rgbaFloat); /* mac 32k limitation */ } - if (ctx->Texture._ReallyEnabled && ctx->Pixel.PixelTextureEnabled) { - GLuint unit; - GLchan primary_rgba[MAX_WIDTH][4]; - DEFARRAY(GLfloat, s, MAX_WIDTH); /* mac 32k limitation */ - DEFARRAY(GLfloat, t, MAX_WIDTH); /* mac 32k limitation */ - DEFARRAY(GLfloat, r, MAX_WIDTH); /* mac 32k limitation */ - DEFARRAY(GLfloat, q, MAX_WIDTH); /* mac 32k limitation */ - CHECKARRAY(s, return); /* mac 32k limitation */ - CHECKARRAY(t, return); - CHECKARRAY(r, return); - CHECKARRAY(q, return); - - /* XXX not sure how multitexture is supposed to work here */ - MEMCPY(primary_rgba, rgba, 4 * width * sizeof(GLchan)); - - for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { - _mesa_pixeltexgen(ctx, width, (const GLchan (*)[4]) rgba, - s, t, r, q); - _swrast_texture_fragments(ctx, unit, width, s, t, r, NULL, - (CONST GLchan (*)[4]) primary_rgba, - rgba); - } - - UNDEFARRAY(s); /* mac 32k limitation */ - UNDEFARRAY(t); - UNDEFARRAY(r); - UNDEFARRAY(q); + if (ctx->Pixel.PixelTextureEnabled && ctx->Texture._EnabledUnits) { + span.end = width; + _swrast_pixel_texture(ctx, &span); } - if (quick_draw && dy >= 0 && dy < ctx->DrawBuffer->Height) { + /* Write color span */ + if (quick_draw && dy >= 0 && dy < (GLint) ctx->DrawBuffer->Height) { (*swrast->Driver.WriteRGBASpan)( ctx, width, destx, dy, - (const GLchan (*)[4])rgba, NULL ); + (const GLchan (*)[4])span.array->rgba, NULL ); } else if (zoom) { - _mesa_write_zoomed_rgba_span( ctx, width, destx, dy, zspan, fogSpan, - (const GLchan (*)[4])rgba, desty); + span.x = destx; + span.y = dy; + span.end = width; + _swrast_write_zoomed_rgba_span(ctx, &span, + (CONST GLchan (*)[4]) span.array->rgba, + desty, 0); } else { - _mesa_write_rgba_span( ctx, width, destx, dy, zspan, fogSpan, rgba, - NULL, GL_BITMAP ); + span.x = destx; + span.y = dy; + span.end = width; + _swrast_write_rgba_span(ctx, &span); } } - /* Restore pixel source to be the draw buffer (for blending, etc) */ - (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, - ctx->Color.DriverDrawBuffer ); - if (overlapping) FREE(tmpImage); } -static void copy_ci_pixels( GLcontext *ctx, - GLint srcx, GLint srcy, GLint width, GLint height, - GLint destx, GLint desty ) +static void +copy_ci_pixels( GLcontext *ctx, GLint srcx, GLint srcy, + GLint width, GLint height, + GLint destx, GLint desty ) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLdepth zspan[MAX_WIDTH]; - GLfloat fogSpan[MAX_WIDTH]; GLuint *tmpImage,*p; GLint sy, dy, stepy; - GLint i, j; + GLint j; GLboolean changeBuffer; const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F; const GLboolean shift_or_offset = ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset; GLint overlapping; + struct sw_span span; + + INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_INDEX); /* Determine if copy should be bottom-to-top or top-to-bottom */ if (srcyPixel.ZoomX, ctx->Pixel.ZoomY); - - if (ctx->Depth.Test || ctx->Fog.Enabled) { - /* fill in array of z values */ - GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->DepthMax); - GLfloat fog; - - if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) - fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterFogCoord); - else - fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance); - - for (i=0;iDrawBuffer == ctx->ReadBuffer) { + overlapping = regions_overlap(srcx, srcy, destx, desty, width, height, + ctx->Pixel.ZoomX, ctx->Pixel.ZoomY); + } + else { + overlapping = GL_FALSE; } + if (ctx->Depth.Test) + _swrast_span_default_z(ctx, &span); + if (ctx->Fog.Enabled) + _swrast_span_default_fog(ctx, &span); + /* If read and draw buffer are different we must do buffer switching */ changeBuffer = ctx->Pixel.ReadBuffer != ctx->Color.DrawBuffer || ctx->DrawBuffer != ctx->ReadBuffer; - (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, - ctx->Pixel.DriverReadBuffer ); - if (overlapping) { GLint ssy = sy; tmpImage = (GLuint *) MALLOC(width * height * sizeof(GLuint)); @@ -641,16 +550,21 @@ static void copy_ci_pixels( GLcontext *ctx, _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" ); return; } + /* setup source */ + if (changeBuffer) + _swrast_use_read_buffer(ctx); + /* read the image */ p = tmpImage; - if (changeBuffer) { - (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, - ctx->Pixel.DriverReadBuffer ); - } for (j = 0; j < height; j++, ssy += stepy) { - _mesa_read_index_span( ctx, ctx->ReadBuffer, width, srcx, ssy, p ); + _swrast_read_index_span( ctx, ctx->ReadBuffer, width, srcx, ssy, p ); p += width; } p = tmpImage; + /* restore to draw buffer */ + if (changeBuffer) { + _swrast_use_draw_buffer(ctx); + changeBuffer = GL_FALSE; + } } else { tmpImage = NULL; /* silence compiler warning */ @@ -658,46 +572,38 @@ static void copy_ci_pixels( GLcontext *ctx, } for (j = 0; j < height; j++, sy += stepy, dy += stepy) { - GLuint indexes[MAX_WIDTH]; + /* Get color indexes */ if (overlapping) { - MEMCPY(indexes, p, width * sizeof(GLuint)); + MEMCPY(span.array->index, p, width * sizeof(GLuint)); p += width; } else { - if (changeBuffer) { - (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, - ctx->Pixel.DriverReadBuffer ); - } - _mesa_read_index_span( ctx, ctx->ReadBuffer, width, srcx, sy, indexes ); - } - - if (changeBuffer) { - /* set read buffer back to draw buffer (in case of logicops) */ - (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, - ctx->Color.DriverDrawBuffer ); + if (changeBuffer) + _swrast_use_read_buffer(ctx); + _swrast_read_index_span( ctx, ctx->ReadBuffer, width, srcx, sy, + span.array->index ); + if (changeBuffer) + _swrast_use_draw_buffer(ctx); } + /* Apply shift, offset, look-up table */ if (shift_or_offset) { - _mesa_shift_and_offset_ci( ctx, width, indexes ); + _mesa_shift_and_offset_ci( ctx, width, span.array->index ); } if (ctx->Pixel.MapColorFlag) { - _mesa_map_ci( ctx, width, indexes ); + _mesa_map_ci( ctx, width, span.array->index ); } - if (zoom) { - _mesa_write_zoomed_index_span(ctx, width, destx, dy, zspan, fogSpan, - indexes, desty ); - } - else { - _mesa_write_index_span(ctx, width, destx, dy, zspan, fogSpan, indexes, - NULL, GL_BITMAP); - } + /* write color indexes */ + span.x = destx; + span.y = dy; + span.end = width; + if (zoom) + _swrast_write_zoomed_index_span(ctx, &span, desty, 0); + else + _swrast_write_index_span(ctx, &span); } - /* Restore pixel source to be the draw buffer (for blending, etc) */ - (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, - ctx->Color.DriverDrawBuffer ); - if (overlapping) FREE(tmpImage); } @@ -707,25 +613,22 @@ static void copy_ci_pixels( GLcontext *ctx, /* * TODO: Optimize!!!! */ -static void copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy, - GLint width, GLint height, - GLint destx, GLint desty ) +static void +copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy, + GLint width, GLint height, + GLint destx, GLint desty ) { - GLfloat depth[MAX_WIDTH]; - GLdepth zspan[MAX_WIDTH]; - GLfloat fogSpan[MAX_WIDTH]; GLfloat *p, *tmpImage; - GLuint indexes[MAX_WIDTH]; GLint sy, dy, stepy; GLint i, j; const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F; GLint overlapping; - DEFMARRAY(GLubyte, rgba, MAX_WIDTH, 4); /* mac 32k limitation */ - CHECKARRAY(rgba, return); /* mac 32k limitation */ + struct sw_span span; + + INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_Z); if (!ctx->Visual.depthBits) { _mesa_error( ctx, GL_INVALID_OPERATION, "glCopyPixels" ); - UNDEFARRAY(rgba); /* mac 32k limitation */ return; } @@ -743,47 +646,28 @@ static void copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy, stepy = 1; } - overlapping = regions_overlap(srcx, srcy, destx, desty, width, height, - ctx->Pixel.ZoomX, ctx->Pixel.ZoomY); - - /* setup colors or indexes */ - if (ctx->Visual.rgbMode) { - GLuint *rgba32 = (GLuint *) rgba; - GLuint color = *(GLuint*)( ctx->Current.Color ); - for (i = 0; i < width; i++) { - rgba32[i] = color; - } + if (ctx->DrawBuffer == ctx->ReadBuffer) { + overlapping = regions_overlap(srcx, srcy, destx, desty, width, height, + ctx->Pixel.ZoomX, ctx->Pixel.ZoomY); } else { - for (i = 0; i < width; i++) { - indexes[i] = ctx->Current.Index; - } + overlapping = GL_FALSE; } - if (ctx->Fog.Enabled) { - GLfloat fog; - - if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) - fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterFogCoord); - else - fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance); - - for (i = 0; i < width; i++) { - fogSpan[i] = fog; - } - } + _swrast_span_default_color(ctx, &span); + if (ctx->Fog.Enabled) + _swrast_span_default_fog(ctx, &span); if (overlapping) { GLint ssy = sy; tmpImage = (GLfloat *) MALLOC(width * height * sizeof(GLfloat)); if (!tmpImage) { _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" ); - UNDEFARRAY(rgba); /* mac 32k limitation */ return; } p = tmpImage; for (j = 0; j < height; j++, ssy += stepy) { - _mesa_read_depth_span_float(ctx, width, srcx, ssy, p); + _swrast_read_depth_span_float(ctx, width, srcx, ssy, p); p += width; } p = tmpImage; @@ -794,52 +678,52 @@ static void copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy, } for (j = 0; j < height; j++, sy += stepy, dy += stepy) { + GLfloat depth[MAX_WIDTH]; + + /* get depth values */ if (overlapping) { MEMCPY(depth, p, width * sizeof(GLfloat)); p += width; } else { - _mesa_read_depth_span_float(ctx, width, srcx, sy, depth); + _swrast_read_depth_span_float(ctx, width, srcx, sy, depth); } + /* apply scale and bias */ for (i = 0; i < width; i++) { GLfloat d = depth[i] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias; - zspan[i] = (GLdepth) (CLAMP(d, 0.0F, 1.0F) * ctx->DepthMax); + span.array->z[i] = (GLdepth) (CLAMP(d, 0.0F, 1.0F) * ctx->DepthMax); } + /* write depth values */ + span.x = destx; + span.y = dy; + span.end = width; if (ctx->Visual.rgbMode) { - if (zoom) { - _mesa_write_zoomed_rgba_span( ctx, width, destx, dy, zspan, - fogSpan, (const GLchan (*)[4])rgba, desty ); - } - else { - _mesa_write_rgba_span( ctx, width, destx, dy, zspan, fogSpan, - rgba, NULL, GL_BITMAP); - } + if (zoom) + _swrast_write_zoomed_rgba_span( ctx, &span, + (const GLchan (*)[4])span.array->rgba, desty, 0 ); + else + _swrast_write_rgba_span(ctx, &span); } else { - if (zoom) { - _mesa_write_zoomed_index_span( ctx, width, destx, dy, - zspan, fogSpan, indexes, desty ); - } - else { - _mesa_write_index_span( ctx, width, destx, dy, - zspan, fogSpan, indexes, NULL, GL_BITMAP ); - } + if (zoom) + _swrast_write_zoomed_index_span( ctx, &span, desty, 0 ); + else + _swrast_write_index_span(ctx, &span); } } - UNDEFARRAY(rgba); /* mac 32k limitation */ - if (overlapping) FREE(tmpImage); } -static void copy_stencil_pixels( GLcontext *ctx, GLint srcx, GLint srcy, - GLint width, GLint height, - GLint destx, GLint desty ) +static void +copy_stencil_pixels( GLcontext *ctx, GLint srcx, GLint srcy, + GLint width, GLint height, + GLint destx, GLint desty ) { GLint sy, dy, stepy; GLint j; @@ -867,8 +751,13 @@ static void copy_stencil_pixels( GLcontext *ctx, GLint srcx, GLint srcy, stepy = 1; } - overlapping = regions_overlap(srcx, srcy, destx, desty, width, height, - ctx->Pixel.ZoomX, ctx->Pixel.ZoomY); + if (ctx->DrawBuffer == ctx->ReadBuffer) { + overlapping = regions_overlap(srcx, srcy, destx, desty, width, height, + ctx->Pixel.ZoomX, ctx->Pixel.ZoomY); + } + else { + overlapping = GL_FALSE; + } if (overlapping) { GLint ssy = sy; @@ -879,7 +768,7 @@ static void copy_stencil_pixels( GLcontext *ctx, GLint srcx, GLint srcy, } p = tmpImage; for (j = 0; j < height; j++, ssy += stepy) { - _mesa_read_stencil_span( ctx, width, srcx, ssy, p ); + _swrast_read_stencil_span( ctx, width, srcx, ssy, p ); p += width; } p = tmpImage; @@ -892,14 +781,16 @@ static void copy_stencil_pixels( GLcontext *ctx, GLint srcx, GLint srcy, for (j = 0; j < height; j++, sy += stepy, dy += stepy) { GLstencil stencil[MAX_WIDTH]; + /* Get stencil values */ if (overlapping) { MEMCPY(stencil, p, width * sizeof(GLstencil)); p += width; } else { - _mesa_read_stencil_span( ctx, width, srcx, sy, stencil ); + _swrast_read_stencil_span( ctx, width, srcx, sy, stencil ); } + /* Apply shift, offset, look-up table */ if (shift_or_offset) { _mesa_shift_and_offset_stencil( ctx, width, stencil ); } @@ -907,11 +798,13 @@ static void copy_stencil_pixels( GLcontext *ctx, GLint srcx, GLint srcy, _mesa_map_stencil( ctx, width, stencil ); } + /* Write stencil values */ if (zoom) { - _mesa_write_zoomed_stencil_span( ctx, width, destx, dy, stencil, desty ); + _swrast_write_zoomed_stencil_span( ctx, width, destx, dy, + stencil, desty, 0 ); } else { - _mesa_write_stencil_span( ctx, width, destx, dy, stencil ); + _swrast_write_stencil_span( ctx, width, destx, dy, stencil ); } } @@ -921,7 +814,6 @@ static void copy_stencil_pixels( GLcontext *ctx, GLint srcx, GLint srcy, - void _swrast_CopyPixels( GLcontext *ctx, GLint srcx, GLint srcy, GLsizei width, GLsizei height,