X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fswrast%2Fs_copypix.c;h=5f8c35daaab20ff9fd34646007ba59337a0641ff;hb=612fc012934d9ec61972c3cfd914923937339611;hp=96172e027125fdd9f351708c1af2d6143873180d;hpb=45015e4d79d63183f6d9c4e4fad655921e07b0ab;p=mesa.git diff --git a/src/mesa/swrast/s_copypix.c b/src/mesa/swrast/s_copypix.c index 96172e02712..5f8c35daaab 100644 --- a/src/mesa/swrast/s_copypix.c +++ b/src/mesa/swrast/s_copypix.c @@ -1,21 +1,21 @@ -/* $Id: s_copypix.c,v 1.5 2000/11/28 00:07:52 brianp Exp $ */ +/* $Id: s_copypix.c,v 1.34 2002/03/14 22:09:25 brianp Exp $ */ /* * Mesa 3-D graphics library - * Version: 3.5 - * - * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. - * + * Version: 4.1 + * + * 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"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -47,23 +47,46 @@ /* - * Determine if there's overlap in an image copy + * Determine if there's overlap in an image copy. + * This test also compensates for the fact that copies are done from + * bottom to top and overlaps can sometimes be handled correctly + * without making a temporary image copy. */ static GLboolean -regions_overlap(int srcx, int srcy, int dstx, int dsty, int width, int height, - float zoomX, float zoomY) +regions_overlap(GLint srcx, GLint srcy, + GLint dstx, GLint dsty, + GLint width, GLint height, + GLfloat zoomX, GLfloat zoomY) { - if ((srcx > dstx + (width * zoomX) + 1) || (srcx + width + 1 < dstx)) { - return GL_FALSE; - } - else if ((srcy < dsty) && (srcy + height < dsty + (height * zoomY))) { - return GL_FALSE; - } - else if ((srcy > dsty) && (srcy + height > dsty + (height * zoomY))) { - return GL_FALSE; + if (zoomX == 1.0 && zoomY == 1.0) { + /* no zoom */ + if (srcx >= dstx + width || (srcx + width <= dstx)) { + return GL_FALSE; + } + else if (srcy < dsty) { /* this is OK */ + return GL_FALSE; + } + else if (srcy > dsty + height) { + return GL_FALSE; + } + else { + return GL_TRUE; + } } else { - return GL_TRUE; + /* add one pixel of slop when zooming, just to be safe */ + if ((srcx > dstx + (width * zoomX) + 1) || (srcx + width + 1 < dstx)) { + return GL_FALSE; + } + else if ((srcy < dsty) && (srcy + height < dsty + (height * zoomY))) { + return GL_FALSE; + } + else if ((srcy > dsty) && (srcy + height > dsty + (height * zoomY))) { + return GL_FALSE; + } + else { + return GL_TRUE; + } } } @@ -76,7 +99,7 @@ static void copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, GLint width, GLint height, GLint destx, GLint desty) { - GLdepth zspan[MAX_WIDTH]; + SWcontext *swrast = SWRAST_CONTEXT(ctx); GLboolean quick_draw; GLint row; GLboolean changeBuffer; @@ -84,16 +107,16 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, 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; + + INIT_SPAN(span); + span.arrayMask |= SPAN_RGBA; + + if (ctx->Depth.Test) + _mesa_span_default_z(ctx, &span); + if (ctx->Fog.Enabled) + _mesa_span_default_fog(ctx, &span); - if (ctx->Depth.Test || ctx->Fog.Enabled) { - /* fill in array of z values */ - GLdepth z = (GLdepth) - (ctx->Current.RasterPos[2] * ctx->Visual.DepthMax); - GLint i; - for (i = 0; i < width; i++) { - zspan[i] = z; - } - } if (SWRAST_CONTEXT(ctx)->_RasterMask == 0 && !zoom @@ -114,20 +137,20 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, /* allocate space for GLfloat image */ tmpImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat)); if (!tmpImage) { - gl_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels"); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels"); return; } convImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat)); if (!convImage) { FREE(tmpImage); - gl_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels"); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels"); return; } dest = tmpImage; if (changeBuffer) { - (*ctx->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, + (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, ctx->Pixel.DriverReadBuffer ); if (ctx->Pixel.DriverReadBuffer == GL_FRONT_LEFT) ctx->ReadBuffer->Alpha = ctx->ReadBuffer->FrontLeftAlpha; @@ -144,7 +167,7 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, for (row = 0; row < height; row++) { GLchan rgba[MAX_WIDTH][4]; GLint i; - gl_read_rgba_span(ctx, ctx->ReadBuffer, width, srcx, srcy + row, rgba); + _mesa_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); @@ -156,14 +179,14 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, /* read from the draw buffer again (in case of blending) */ if (changeBuffer) { - (*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, + (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, ctx->Color.DriverDrawBuffer ); ctx->ReadBuffer->Alpha = saveReadAlpha; } /* 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) { @@ -195,7 +218,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) { @@ -221,7 +244,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 */ @@ -230,41 +252,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); + span.color.rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX); + span.color.rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX); + span.color.rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX); + span.color.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 < MAX_TEXTURE_UNITS; unit++) { - _mesa_pixeltexgen(ctx, width, (const GLchan (*)[4]) rgba, - s, t, r, q); - gl_texture_pixels(ctx, unit, width, s, t, r, NULL, - primary_rgba, rgba); - } + if (ctx->Pixel.PixelTextureEnabled && ctx->Texture._ReallyEnabled) { + span.end = width; + _swrast_pixel_texture(ctx, &span); } /* write row to framebuffer */ dy = desty + row; if (quick_draw && dy >= 0 && dy < ctx->DrawBuffer->Height) { - (*ctx->Driver.WriteRGBASpan)( ctx, width, destx, dy, - (const GLchan (*)[4])rgba, NULL ); + (*swrast->Driver.WriteRGBASpan)( ctx, width, destx, dy, + (const GLchan (*)[4])span.color.rgba, NULL ); } else if (zoom) { - gl_write_zoomed_rgba_span( ctx, width, destx, dy, zspan, 0, - (const GLchan (*)[4])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 { - gl_write_rgba_span( ctx, width, destx, dy, zspan, 0, rgba, GL_BITMAP ); + span.x = destx; + span.y = dy; + span.end = width; + _mesa_write_rgba_span(ctx, &span, GL_BITMAP); } } @@ -279,17 +297,19 @@ static void copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, GLint width, GLint height, GLint destx, GLint desty) { - GLdepth zspan[MAX_WIDTH]; - GLchan rgba[MAX_WIDTH][4]; + SWcontext *swrast = SWRAST_CONTEXT(ctx); 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); + span.arrayMask |= SPAN_RGBA; if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) { copy_conv_rgba_pixels(ctx, srcx, srcy, width, height, destx, desty); @@ -313,13 +333,10 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, 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->Visual.DepthMax); - for (i=0;iDepth.Test) + _mesa_span_default_z(ctx, &span); + if (ctx->Fog.Enabled) + _mesa_span_default_fog(ctx, &span); if (SWRAST_CONTEXT(ctx)->_RasterMask == 0 && !zoom @@ -336,19 +353,19 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, changeBuffer = ctx->Pixel.ReadBuffer != ctx->Color.DrawBuffer || ctx->DrawBuffer != ctx->ReadBuffer; - (*ctx->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, + (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, ctx->Pixel.DriverReadBuffer ); if (overlapping) { GLint ssy = sy; tmpImage = (GLchan *) MALLOC(width * height * sizeof(GLchan) * 4); if (!tmpImage) { - gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" ); + _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" ); return; } p = tmpImage; if (changeBuffer) { - (*ctx->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, + (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, ctx->Pixel.DriverReadBuffer ); if (ctx->Pixel.DriverReadBuffer == GL_FRONT_LEFT) ctx->ReadBuffer->Alpha = ctx->ReadBuffer->FrontLeftAlpha; @@ -360,9 +377,9 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, ctx->ReadBuffer->Alpha = ctx->ReadBuffer->BackRightAlpha; } for (j = 0; j < height; j++, ssy += stepy) { - gl_read_rgba_span( ctx, ctx->ReadBuffer, width, srcx, ssy, + _mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, srcx, ssy, (GLchan (*)[4]) p ); - p += (width * sizeof(GLchan) * 4); + p += width * 4; } p = tmpImage; } @@ -375,13 +392,13 @@ 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); + MEMCPY(span.color.rgba, p, width * sizeof(GLchan) * 4); + p += width * 4; } else { /* get from framebuffer */ if (changeBuffer) { - (*ctx->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, + (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, ctx->Pixel.DriverReadBuffer ); if (ctx->Pixel.DriverReadBuffer == GL_FRONT_LEFT) { ctx->ReadBuffer->Alpha = ctx->ReadBuffer->FrontLeftAlpha; @@ -396,26 +413,28 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, ctx->ReadBuffer->Alpha = ctx->ReadBuffer->BackRightAlpha; } } - gl_read_rgba_span( ctx, ctx->ReadBuffer, width, srcx, sy, rgba ); + _mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, srcx, sy, span.color.rgba ); } if (changeBuffer) { /* read from the draw buffer again (in case of blending) */ - (*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, + (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, ctx->Color.DriverDrawBuffer ); ctx->ReadBuffer->Alpha = saveReadAlpha; } if (transferOps) { const GLfloat scale = (1.0F / CHAN_MAXF); - GLfloat rgbaFloat[MAX_WIDTH][4]; - GLuint k; + GLint k; + DEFMARRAY(GLfloat, rgbaFloat, MAX_WIDTH, 4); /* mac 32k limitation */ + CHECKARRAY(rgbaFloat, return); + /* 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.color.rgba[k][RCOMP] * scale; + rgbaFloat[k][GCOMP] = (GLfloat) span.color.rgba[k][GCOMP] * scale; + rgbaFloat[k][BCOMP] = (GLfloat) span.color.rgba[k][BCOMP] * scale; + rgbaFloat[k][ACOMP] = (GLfloat) span.color.rgba[k][ACOMP] * scale; } /* scale & bias */ if (transferOps & IMAGE_SCALE_BIAS_BIT) { @@ -435,11 +454,11 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, } /* convolution */ if (transferOps & IMAGE_CONVOLUTION_BIT) { - /* XXX to do */ + abort(); /* should never get here; caught at top of function */ } /* GL_POST_CONVOLUTION_RED/GREEN/BLUE/ALPHA_SCALE/BIAS */ if (transferOps & IMAGE_POST_CONVOLUTION_SCALE_BIAS) { - _mesa_scale_and_bias_rgba(ctx, width, rgba, + _mesa_scale_and_bias_rgba(ctx, width, rgbaFloat, ctx->Pixel.PostConvolutionScale[RCOMP], ctx->Pixel.PostConvolutionScale[GCOMP], ctx->Pixel.PostConvolutionScale[BCOMP], @@ -475,44 +494,41 @@ 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.color.rgba[k][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX); + span.color.rgba[k][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX); + span.color.rgba[k][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX); + span.color.rgba[k][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX); } + UNDEFARRAY(rgbaFloat); /* mac 32k limitation */ } - 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 < MAX_TEXTURE_UNITS; unit++) { - _mesa_pixeltexgen(ctx, width, (const GLchan (*)[4]) rgba, - s, t, r, q); - gl_texture_pixels(ctx, unit, width, s, t, r, NULL, - primary_rgba, rgba); - } + if (ctx->Pixel.PixelTextureEnabled && ctx->Texture._ReallyEnabled) { + span.end = width; + _swrast_pixel_texture(ctx, &span); } if (quick_draw && dy >= 0 && dy < ctx->DrawBuffer->Height) { - (*ctx->Driver.WriteRGBASpan)( ctx, width, destx, dy, - (const GLchan (*)[4])rgba, NULL ); + (*swrast->Driver.WriteRGBASpan)( ctx, width, destx, dy, + (const GLchan (*)[4])span.color.rgba, NULL ); } else if (zoom) { - gl_write_zoomed_rgba_span( ctx, width, destx, dy, zspan, 0, - (const GLchan (*)[4])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 { - gl_write_rgba_span( ctx, width, destx, dy, zspan, 0, rgba, GL_BITMAP ); + span.x = destx; + span.y = dy; + span.end = width; + _mesa_write_rgba_span(ctx, &span, GL_BITMAP); } } /* Restore pixel source to be the draw buffer (for blending, etc) */ - (*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, + (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, ctx->Color.DriverDrawBuffer ); if (overlapping) @@ -524,14 +540,18 @@ static void copy_ci_pixels( GLcontext *ctx, GLint srcx, GLint srcy, GLint width, GLint height, GLint destx, GLint desty ) { - GLdepth zspan[MAX_WIDTH]; + SWcontext *swrast = SWRAST_CONTEXT(ctx); 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); + span.arrayMask |= 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->Visual.DepthMax); - for (i=0;iDepth.Test) + _mesa_span_default_z(ctx, &span); + if (ctx->Fog.Enabled) + _mesa_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; - (*ctx->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, + (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, ctx->Pixel.DriverReadBuffer ); if (overlapping) { GLint ssy = sy; tmpImage = (GLuint *) MALLOC(width * height * sizeof(GLuint)); if (!tmpImage) { - gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" ); + _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" ); return; } p = tmpImage; if (changeBuffer) { - (*ctx->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, + (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, ctx->Pixel.DriverReadBuffer ); } for (j = 0; j < height; j++, ssy += stepy) { - gl_read_index_span( ctx, ctx->ReadBuffer, width, srcx, ssy, p ); + _mesa_read_index_span( ctx, ctx->ReadBuffer, width, srcx, ssy, p ); p += width; } p = tmpImage; @@ -589,42 +606,43 @@ static void copy_ci_pixels( GLcontext *ctx, } for (j = 0; j < height; j++, sy += stepy, dy += stepy) { - GLuint indexes[MAX_WIDTH]; if (overlapping) { - MEMCPY(indexes, p, width * sizeof(GLuint)); + MEMCPY(span.color.index, p, width * sizeof(GLuint)); p += width; } else { if (changeBuffer) { - (*ctx->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, + (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, ctx->Pixel.DriverReadBuffer ); } - gl_read_index_span( ctx, ctx->ReadBuffer, width, srcx, sy, indexes ); + _mesa_read_index_span( ctx, ctx->ReadBuffer, width, srcx, sy, + span.color.index ); } if (changeBuffer) { /* set read buffer back to draw buffer (in case of logicops) */ - (*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, + (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, ctx->Color.DriverDrawBuffer ); } if (shift_or_offset) { - _mesa_shift_and_offset_ci( ctx, width, indexes ); + _mesa_shift_and_offset_ci( ctx, width, span.color.index ); } if (ctx->Pixel.MapColorFlag) { - _mesa_map_ci( ctx, width, indexes ); + _mesa_map_ci( ctx, width, span.color.index ); } - if (zoom) { - gl_write_zoomed_index_span( ctx, width, destx, dy, zspan, 0, indexes, desty ); - } - else { - gl_write_index_span(ctx, width, destx, dy, zspan, 0, indexes, GL_BITMAP); - } + 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) */ - (*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, + (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, ctx->Color.DriverDrawBuffer ); if (overlapping) @@ -641,17 +659,18 @@ static void copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy, GLint destx, GLint desty ) { GLfloat depth[MAX_WIDTH]; - GLdepth zspan[MAX_WIDTH]; GLfloat *p, *tmpImage; - GLuint indexes[MAX_WIDTH]; - GLchan rgba[MAX_WIDTH][4]; GLint sy, dy, stepy; GLint i, j; const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F; GLint overlapping; + struct sw_span span; - if (!ctx->ReadBuffer->DepthBuffer || !ctx->DrawBuffer->DepthBuffer) { - gl_error( ctx, GL_INVALID_OPERATION, "glCopyPixels" ); + INIT_SPAN(span); + span.arrayMask |= SPAN_Z; + + if (!ctx->Visual.depthBits) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glCopyPixels" ); return; } @@ -672,25 +691,15 @@ static void copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy, overlapping = regions_overlap(srcx, srcy, destx, desty, width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY); - /* setup colors or indexes */ - if (ctx->Visual.RGBAflag) { - GLuint *rgba32 = (GLuint *) rgba; - GLuint color = *(GLuint*)( ctx->Current.Color ); - for (i = 0; i < width; i++) { - rgba32[i] = color; - } - } - else { - for (i = 0; i < width; i++) { - indexes[i] = ctx->Current.Index; - } - } + _mesa_span_default_color(ctx, &span); + if (ctx->Fog.Enabled) + _mesa_span_default_fog(ctx, &span); if (overlapping) { GLint ssy = sy; tmpImage = (GLfloat *) MALLOC(width * height * sizeof(GLfloat)); if (!tmpImage) { - gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" ); + _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" ); return; } p = tmpImage; @@ -716,33 +725,30 @@ static void copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy, 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->Visual.DepthMax); + span.zArray[i] = (GLdepth) (CLAMP(d, 0.0F, 1.0F) * ctx->DepthMax); } - if (ctx->Visual.RGBAflag) { - if (zoom) { - gl_write_zoomed_rgba_span( ctx, width, destx, dy, zspan, 0, - (const GLchan (*)[4])rgba, desty ); - } - else { - gl_write_rgba_span( ctx, width, destx, dy, zspan, 0, - rgba, GL_BITMAP); - } + span.x = destx; + span.y = dy; + span.end = width; + if (ctx->Visual.rgbMode) { + 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) { - gl_write_zoomed_index_span( ctx, width, destx, dy, - zspan, 0, indexes, desty ); - } - else { - gl_write_index_span( ctx, width, destx, dy, - zspan, 0, indexes, GL_BITMAP ); - } + if (zoom) + _mesa_write_zoomed_index_span( ctx, &span, desty ); + else + _mesa_write_index_span(ctx, &span, GL_BITMAP); } } - if (overlapping) - FREE(tmpImage); + if (overlapping) + FREE(tmpImage); } @@ -758,8 +764,8 @@ static void copy_stencil_pixels( GLcontext *ctx, GLint srcx, GLint srcy, const GLboolean shift_or_offset = ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset; GLint overlapping; - if (!ctx->DrawBuffer->Stencil || !ctx->ReadBuffer->Stencil) { - gl_error( ctx, GL_INVALID_OPERATION, "glCopyPixels" ); + if (!ctx->Visual.stencilBits) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glCopyPixels" ); return; } @@ -784,7 +790,7 @@ static void copy_stencil_pixels( GLcontext *ctx, GLint srcx, GLint srcy, GLint ssy = sy; tmpImage = (GLstencil *) MALLOC(width * height * sizeof(GLstencil)); if (!tmpImage) { - gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" ); + _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" ); return; } p = tmpImage; @@ -818,7 +824,7 @@ static void copy_stencil_pixels( GLcontext *ctx, GLint srcx, GLint srcy, } if (zoom) { - gl_write_zoomed_stencil_span( ctx, width, destx, dy, stencil, desty ); + _mesa_write_zoomed_stencil_span( ctx, width, destx, dy, stencil, desty ); } else { _mesa_write_stencil_span( ctx, width, destx, dy, stencil ); @@ -838,13 +844,16 @@ _swrast_CopyPixels( GLcontext *ctx, GLint destx, GLint desty, GLenum type ) { - if (SWRAST_CONTEXT(ctx)->NewState) + SWcontext *swrast = SWRAST_CONTEXT(ctx); + RENDER_START(swrast,ctx); + + if (swrast->NewState) _swrast_validate_derived( ctx ); - if (type == GL_COLOR && ctx->Visual.RGBAflag) { + if (type == GL_COLOR && ctx->Visual.rgbMode) { copy_rgba_pixels( ctx, srcx, srcy, width, height, destx, desty ); } - else if (type == GL_COLOR && !ctx->Visual.RGBAflag) { + else if (type == GL_COLOR && !ctx->Visual.rgbMode) { copy_ci_pixels( ctx, srcx, srcy, width, height, destx, desty ); } else if (type == GL_DEPTH) { @@ -854,6 +863,8 @@ _swrast_CopyPixels( GLcontext *ctx, copy_stencil_pixels( ctx, srcx, srcy, width, height, destx, desty ); } else { - gl_error( ctx, GL_INVALID_ENUM, "glCopyPixels" ); + _mesa_error( ctx, GL_INVALID_ENUM, "glCopyPixels" ); } + + RENDER_FINISH(swrast,ctx); }