-/* $Id: s_copypix.c,v 1.27 2002/01/10 16:54:29 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
+ * 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"),
#include "s_context.h"
#include "s_depth.h"
-#include "s_fog.h"
#include "s_histogram.h"
#include "s_pixeltex.h"
#include "s_span.h"
else if (srcy < dsty) { /* this is OK */
return GL_FALSE;
}
+ else if (srcy > dsty + height) {
+ return GL_FALSE;
+ }
else {
return GL_TRUE;
}
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;
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);
+ span.arrayMask |= 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)
+ _mesa_span_default_z(ctx, &span);
+ if (ctx->Fog.Enabled)
+ _mesa_span_default_fog(ctx, &span);
- for (i = 0; i < width; i++) {
- zspan[i] = z;
- fogSpan[i] = fog;
- }
- }
if (SWRAST_CONTEXT(ctx)->_RasterMask == 0
&& !zoom
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 */
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) {
- GLchan primary_rgba[MAX_WIDTH][4];
- GLuint unit;
- DEFMARRAY(GLfloat, texcoord, MAX_WIDTH, 4); /* mac 32k limitation */
- CHECKARRAY(texcoord, return); /* mac 32k limitation */
-
- /* 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,
- texcoord);
- _old_swrast_texture_fragments( ctx, unit, width, texcoord, NULL,
- (CONST GLchan (*)[4]) primary_rgba,
- rgba);
- }
- UNDEFARRAY(texcoord); /* mac 32k limitation */
+ 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) {
(*swrast->Driver.WriteRGBASpan)( ctx, width, destx, dy,
- (const GLchan (*)[4])rgba, NULL );
+ (const GLchan (*)[4])span.color.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;
+ _mesa_write_zoomed_rgba_span(ctx, &span,
+ (CONST GLchan (*)[4])span.color.rgba,
+ desty);
}
else {
- _old_write_rgba_span( ctx, width, destx, dy, zspan, fogSpan, rgba,
- NULL, GL_BITMAP );
+ span.x = destx;
+ span.y = dy;
+ span.end = width;
+ _mesa_write_rgba_span(ctx, &span, GL_BITMAP);
}
}
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);
+ span.arrayMask |= SPAN_RGBA;
if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) {
copy_conv_rgba_pixels(ctx, srcx, srcy, width, height, destx, desty);
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;i<width;i++) {
- zspan[i] = z;
- fogSpan[i] = fog;
- }
- }
+ 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 == 0
&& !zoom
for (j = 0; j < height; j++, ssy += stepy) {
_mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, srcx, ssy,
(GLchan (*)[4]) p );
- p += (width * sizeof(GLchan) * 4);
+ p += width * 4;
}
p = tmpImage;
}
/* 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 */
ctx->ReadBuffer->Alpha = ctx->ReadBuffer->BackRightAlpha;
}
}
- _mesa_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) {
/* 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) {
}
/* 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) {
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) {
- GLuint unit;
- GLchan primary_rgba[MAX_WIDTH][4];
- DEFMARRAY(GLfloat, texcoord, MAX_WIDTH, 4); /* mac 32k limitation */
- CHECKARRAY(texcoord, return); /* mac 32k limitation */
-
- /* 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,
- texcoord);
- _old_swrast_texture_fragments( ctx, unit, width, texcoord, NULL,
- (CONST GLchan (*)[4]) primary_rgba,
- rgba);
- }
-
- UNDEFARRAY(texcoord); /* mac 32k limitation */
+ if (ctx->Pixel.PixelTextureEnabled && ctx->Texture._ReallyEnabled) {
+ span.end = width;
+ _swrast_pixel_texture(ctx, &span);
}
if (quick_draw && dy >= 0 && dy < ctx->DrawBuffer->Height) {
(*swrast->Driver.WriteRGBASpan)( ctx, width, destx, dy,
- (const GLchan (*)[4])rgba, NULL );
+ (const GLchan (*)[4])span.color.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;
+ _mesa_write_zoomed_rgba_span(ctx, &span,
+ (CONST GLchan (*)[4]) span.color.rgba,
+ desty);
}
else {
- _old_write_rgba_span( ctx, width, destx, dy, zspan, fogSpan, rgba,
- NULL, GL_BITMAP );
+ span.x = destx;
+ span.y = dy;
+ span.end = width;
+ _mesa_write_rgba_span(ctx, &span, GL_BITMAP);
}
}
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);
+ span.arrayMask |= SPAN_INDEX;
/* Determine if copy should be bottom-to-top or top-to-bottom */
if (srcy<desty) {
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;i<width;i++) {
- zspan[i] = z;
- fogSpan[i] = fog;
- }
- }
+ if (ctx->Depth.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
}
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 {
(*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
ctx->Pixel.DriverReadBuffer );
}
- _mesa_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) {
}
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) {
- _mesa_write_zoomed_index_span(ctx, width, destx, dy, zspan, fogSpan,
- indexes, desty );
- }
- else {
- _old_write_index_span(ctx, width, destx, dy, zspan, fogSpan, indexes,
- NULL, 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) */
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(GLchan, rgba, MAX_WIDTH, 4); /* mac 32k limitation */
- CHECKARRAY(rgba, return); /* mac 32k limitation */
+ struct sw_span span;
+
+ INIT_SPAN(span);
+ span.arrayMask |= SPAN_Z;
if (!ctx->Visual.depthBits) {
_mesa_error( ctx, GL_INVALID_OPERATION, "glCopyPixels" );
- UNDEFARRAY(rgba); /* mac 32k limitation */
return;
}
overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
- /* setup colors or indexes */
- if (ctx->Visual.rgbMode) {
- GLchan r, g, b, a;
- UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0]);
- UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1]);
- UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2]);
- UNCLAMPED_FLOAT_TO_CHAN(a, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]);
- for (i = 0; i < width; i++) {
- rgba[i][RCOMP] = r;
- rgba[i][GCOMP] = g;
- rgba[i][BCOMP] = b;
- rgba[i][ACOMP] = a;
- }
- }
- else {
- for (i = 0; i < width; i++) {
- indexes[i] = ctx->Current.Index;
- }
- }
-
- 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;
- }
- }
+ _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) {
_mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
- UNDEFARRAY(rgba); /* mac 32k limitation */
return;
}
p = tmpImage;
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.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, zspan,
- fogSpan, (const GLchan (*)[4])rgba, desty );
- }
- else {
- _old_write_rgba_span( ctx, width, destx, dy, zspan, fogSpan,
- (GLchan (*)[4])rgba, NULL, GL_BITMAP);
- }
+ 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, width, destx, dy,
- zspan, fogSpan, indexes, desty );
- }
- else {
- _old_write_index_span( ctx, width, destx, dy,
- zspan, fogSpan, indexes, NULL, GL_BITMAP );
- }
+ if (zoom)
+ _mesa_write_zoomed_index_span( ctx, &span, desty );
+ else
+ _mesa_write_index_span(ctx, &span, GL_BITMAP);
}
}
- UNDEFARRAY(rgba); /* mac 32k limitation */
-
if (overlapping)
FREE(tmpImage);
}