-/* $Id: s_copypix.c,v 1.4 2000/11/10 18:29:18 brianp Exp $ */
+/* $Id: s_copypix.c,v 1.13 2001/03/03 20:33:30 brianp Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.5
*
- * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2001 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"),
/*
- * 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 {
+ 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;
+ }
}
}
if (ctx->Depth.Test || ctx->Fog.Enabled) {
/* fill in array of z values */
GLdepth z = (GLdepth)
- (ctx->Current.RasterPos[2] * ctx->Visual.DepthMax);
+ (ctx->Current.RasterPos[2] * ctx->DepthMax);
GLint i;
for (i = 0; i < width; i++) {
zspan[i] = z;
/* 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;
}
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);
/* scale & bias */
if (transferOps & IMAGE_SCALE_BIAS_BIT) {
- _mesa_scale_and_bias_rgba(ctx, width, rgba);
+ _mesa_scale_and_bias_rgba(ctx, width, rgba,
+ ctx->Pixel.RedScale, ctx->Pixel.GreenScale,
+ ctx->Pixel.BlueScale, ctx->Pixel.AlphaScale,
+ ctx->Pixel.RedBias, ctx->Pixel.GreenBias,
+ ctx->Pixel.BlueBias, ctx->Pixel.AlphaBias);
}
/* color map lookup */
if (transferOps & IMAGE_MAP_COLOR_BIT) {
MEMCPY(primary_rgba, rgba, 4 * width * sizeof(GLchan));
- for (unit = 0; unit < MAX_TEXTURE_UNITS; unit++) {
+ for (unit = 0; unit < ctx->Const.MaxTextureUnits; 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);
+ _swrast_texture_fragments(ctx, unit, width, s, t, r, NULL,
+ (CONST GLchan (*)[4]) primary_rgba,
+ rgba);
}
}
(const GLchan (*)[4])rgba, NULL );
}
else if (zoom) {
- gl_write_zoomed_rgba_span( ctx, width, destx, dy, zspan, 0,
+ _mesa_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 );
+ _mesa_write_rgba_span( ctx, width, destx, dy, zspan, 0, rgba, GL_BITMAP );
}
}
if (ctx->Depth.Test || ctx->Fog.Enabled) {
/* fill in array of z values */
- GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->Visual.DepthMax);
+ GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->DepthMax);
for (i=0;i<width;i++) {
zspan[i] = z;
}
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;
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);
}
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, rgba );
}
if (changeBuffer) {
}
/* scale & bias */
if (transferOps & IMAGE_SCALE_BIAS_BIT) {
- _mesa_scale_and_bias_rgba(ctx, width, rgbaFloat);
+ _mesa_scale_and_bias_rgba(ctx, width, rgbaFloat,
+ ctx->Pixel.RedScale, ctx->Pixel.GreenScale,
+ ctx->Pixel.BlueScale, ctx->Pixel.AlphaScale,
+ ctx->Pixel.RedBias, ctx->Pixel.GreenBias,
+ ctx->Pixel.BlueBias, ctx->Pixel.AlphaBias);
}
/* color map lookup */
if (transferOps & IMAGE_MAP_COLOR_BIT) {
if (transferOps & IMAGE_CONVOLUTION_BIT) {
/* XXX to do */
}
+ /* GL_POST_CONVOLUTION_RED/GREEN/BLUE/ALPHA_SCALE/BIAS */
+ if (transferOps & IMAGE_POST_CONVOLUTION_SCALE_BIAS) {
+ _mesa_scale_and_bias_rgba(ctx, width, rgbaFloat,
+ ctx->Pixel.PostConvolutionScale[RCOMP],
+ ctx->Pixel.PostConvolutionScale[GCOMP],
+ ctx->Pixel.PostConvolutionScale[BCOMP],
+ ctx->Pixel.PostConvolutionScale[ACOMP],
+ ctx->Pixel.PostConvolutionBias[RCOMP],
+ ctx->Pixel.PostConvolutionBias[GCOMP],
+ ctx->Pixel.PostConvolutionBias[BCOMP],
+ ctx->Pixel.PostConvolutionBias[ACOMP]);
+ }
/* GL_POST_CONVOLUTION_COLOR_TABLE lookup */
if (transferOps & IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT) {
_mesa_lookup_rgba(&ctx->PostConvolutionColorTable, width, rgbaFloat);
MEMCPY(primary_rgba, rgba, 4 * width * sizeof(GLchan));
- for (unit = 0; unit < MAX_TEXTURE_UNITS; unit++) {
+ for (unit = 0; unit < ctx->Const.MaxTextureUnits; 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);
+ _swrast_texture_fragments(ctx, unit, width, s, t, r, NULL,
+ (CONST GLchan (*)[4]) primary_rgba,
+ rgba);
}
}
(const GLchan (*)[4])rgba, NULL );
}
else if (zoom) {
- gl_write_zoomed_rgba_span( ctx, width, destx, dy, zspan, 0,
+ _mesa_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 );
+ _mesa_write_rgba_span( ctx, width, destx, dy, zspan, 0, rgba, GL_BITMAP );
}
}
if (ctx->Depth.Test || ctx->Fog.Enabled) {
/* fill in array of z values */
- GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->Visual.DepthMax);
+ GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->DepthMax);
for (i=0;i<width;i++) {
zspan[i] = z;
}
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;
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;
(*ctx->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, indexes );
}
if (changeBuffer) {
}
if (zoom) {
- gl_write_zoomed_index_span( ctx, width, destx, dy, zspan, 0, indexes, desty );
+ _mesa_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);
+ _mesa_write_index_span(ctx, width, destx, dy, zspan, 0, indexes, GL_BITMAP);
}
}
const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
GLint overlapping;
- if (!ctx->ReadBuffer->DepthBuffer || !ctx->DrawBuffer->DepthBuffer) {
- gl_error( ctx, GL_INVALID_OPERATION, "glCopyPixels" );
+ if (!ctx->Visual.depthBits) {
+ _mesa_error( ctx, GL_INVALID_OPERATION, "glCopyPixels" );
return;
}
ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
/* setup colors or indexes */
- if (ctx->Visual.RGBAflag) {
+ if (ctx->Visual.rgbMode) {
GLuint *rgba32 = (GLuint *) rgba;
GLuint color = *(GLuint*)( ctx->Current.Color );
for (i = 0; i < width; i++) {
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;
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);
+ zspan[i] = (GLdepth) (CLAMP(d, 0.0F, 1.0F) * ctx->DepthMax);
}
- if (ctx->Visual.RGBAflag) {
+ if (ctx->Visual.rgbMode) {
if (zoom) {
- gl_write_zoomed_rgba_span( ctx, width, destx, dy, zspan, 0,
+ _mesa_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,
+ _mesa_write_rgba_span( ctx, width, destx, dy, zspan, 0,
rgba, GL_BITMAP);
}
}
else {
if (zoom) {
- gl_write_zoomed_index_span( ctx, width, destx, dy,
+ _mesa_write_zoomed_index_span( ctx, width, destx, dy,
zspan, 0, indexes, desty );
}
else {
- gl_write_index_span( ctx, width, destx, dy,
+ _mesa_write_index_span( ctx, width, destx, dy,
zspan, 0, indexes, GL_BITMAP );
}
}
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;
}
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;
}
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 );
if (SWRAST_CONTEXT(ctx)->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) {
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" );
}
}