summaryrefslogtreecommitdiff
path: root/xc/extras/Mesa/src/copypix.c
diff options
context:
space:
mode:
Diffstat (limited to 'xc/extras/Mesa/src/copypix.c')
-rw-r--r--xc/extras/Mesa/src/copypix.c256
1 files changed, 141 insertions, 115 deletions
diff --git a/xc/extras/Mesa/src/copypix.c b/xc/extras/Mesa/src/copypix.c
index 912fb6a4b..192471bbe 100644
--- a/xc/extras/Mesa/src/copypix.c
+++ b/xc/extras/Mesa/src/copypix.c
@@ -1,10 +1,10 @@
-/* $Id: copypix.c,v 1.3 1999/12/14 02:39:38 daryll Exp $ */
+/* $Id: copypix.c,v 1.4 2000/01/30 00:27:01 brianp Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.1
+ * Version: 3.3
*
- * Copyright (C) 1999 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2000 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"),
@@ -25,22 +25,16 @@
*/
-
-
-
#ifdef PC_HEADER
#include "all.h"
#else
-#ifndef XFree86Server
-#include <string.h>
-#else
-#include "GL/xf86glx.h"
-#endif
+#include "glheader.h"
#include "context.h"
#include "copypix.h"
#include "depth.h"
#include "feedback.h"
#include "macros.h"
+#include "mem.h"
#include "mmath.h"
#include "pixel.h"
#include "span.h"
@@ -50,6 +44,7 @@
#endif
+
/*
* Determine if there's overlap in an image copy
*/
@@ -73,8 +68,7 @@ regions_overlap(int srcx, int srcy, int dstx, int dsty, int width, int height,
-
-static void copy_rgba_pixels( GLcontext* ctx,
+static void copy_rgba_pixels( GLcontext *ctx,
GLint srcx, GLint srcy,
GLint width, GLint height,
GLint destx, GLint desty )
@@ -86,12 +80,12 @@ static void copy_rgba_pixels( GLcontext* ctx,
GLint sy, dy, stepy;
GLint i, j;
GLboolean changeBuffer;
- GLubyte *saveAlpha;
- const GLboolean zoom = ctx->Pixel.ZoomX!=1.0F || ctx->Pixel.ZoomY!=1.0F;
- GLboolean needbuffer;
+ GLubyte *saveReadAlpha;
+ const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
+ GLint overlapping;
/* Determine if copy should be done bottom-to-top or top-to-bottom */
- if (srcy<desty) {
+ if (srcy < desty) {
/* top-down max-to-min */
sy = srcy + height - 1;
dy = desty + height - 1;
@@ -104,8 +98,8 @@ static void copy_rgba_pixels( GLcontext* ctx,
stepy = 1;
}
- needbuffer = regions_overlap(srcx, srcy, destx, desty, width, height,
- ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
+ 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 */
@@ -115,8 +109,10 @@ static void copy_rgba_pixels( GLcontext* ctx,
}
}
- if (ctx->RasterMask==0 && !zoom
- && destx>=0 && destx+width<=ctx->Buffer->Width) {
+ if (ctx->RasterMask == 0
+ && !zoom
+ && destx >= 0
+ && destx + width <= ctx->DrawBuffer->Width) {
quick_draw = GL_TRUE;
}
else {
@@ -124,64 +120,83 @@ static void copy_rgba_pixels( GLcontext* ctx,
}
/* If read and draw buffer are different we must do buffer switching */
- saveAlpha = ctx->Buffer->Alpha;
- changeBuffer = ctx->Pixel.ReadBuffer != ctx->Color.DrawBuffer;
+ saveReadAlpha = ctx->ReadBuffer->Alpha;
+ changeBuffer = ctx->Pixel.ReadBuffer != ctx->Color.DrawBuffer
+ || ctx->DrawBuffer != ctx->ReadBuffer;
- if (needbuffer) {
+ if (overlapping) {
GLint ssy = sy;
- prgba = (GLubyte *) MALLOC(width*height*sizeof(GLubyte)*4);
+ prgba = (GLubyte *) MALLOC(width * height * sizeof(GLubyte) * 4);
if (!prgba) {
gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
return;
}
p = prgba;
if (changeBuffer) {
- (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.DriverReadBuffer );
+ (*ctx->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
+ ctx->Pixel.DriverReadBuffer );
if (ctx->Pixel.DriverReadBuffer == GL_FRONT_LEFT)
- ctx->Buffer->Alpha = ctx->Buffer->FrontLeftAlpha;
+ ctx->ReadBuffer->Alpha = ctx->ReadBuffer->FrontLeftAlpha;
else if (ctx->Pixel.DriverReadBuffer == GL_BACK_LEFT)
- ctx->Buffer->Alpha = ctx->Buffer->BackLeftAlpha;
+ ctx->ReadBuffer->Alpha = ctx->ReadBuffer->BackLeftAlpha;
else if (ctx->Pixel.DriverReadBuffer == GL_FRONT_RIGHT)
- ctx->Buffer->Alpha = ctx->Buffer->FrontRightAlpha;
+ ctx->ReadBuffer->Alpha = ctx->ReadBuffer->FrontRightAlpha;
else
- ctx->Buffer->Alpha = ctx->Buffer->BackRightAlpha;
+ ctx->ReadBuffer->Alpha = ctx->ReadBuffer->BackRightAlpha;
}
- for (j=0; j<height; j++, ssy+=stepy) {
- gl_read_rgba_span( ctx, width, srcx, ssy,(GLubyte (*)[4]) p );
- p += (width*sizeof(GLubyte)*4);
+ for (j = 0; j < height; j++, ssy += stepy) {
+ gl_read_rgba_span( ctx, ctx->ReadBuffer, width, srcx, ssy,
+ (GLubyte (*)[4]) p );
+ p += (width * sizeof(GLubyte) * 4);
}
p = prgba;
}
+ else {
+ prgba = NULL; /* silence compiler warnings */
+ p = NULL;
+ }
- for (j=0; j<height; j++, sy+=stepy, dy+=stepy) {
- if (needbuffer) {
+ for (j = 0; j < height; j++, sy += stepy, dy += stepy) {
+ if (overlapping) {
MEMCPY(rgba, p, width * sizeof(GLubyte) * 4);
p += (width * sizeof(GLubyte) * 4);
}
else {
if (changeBuffer) {
- (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.DriverReadBuffer );
- if (ctx->Pixel.DriverReadBuffer == GL_FRONT_LEFT)
- ctx->Buffer->Alpha = ctx->Buffer->FrontLeftAlpha;
- else if (ctx->Pixel.DriverReadBuffer == GL_BACK_LEFT)
- ctx->Buffer->Alpha = ctx->Buffer->BackLeftAlpha;
- else if (ctx->Pixel.DriverReadBuffer == GL_FRONT_RIGHT)
- ctx->Buffer->Alpha = ctx->Buffer->FrontRightAlpha;
- else
- ctx->Buffer->Alpha = ctx->Buffer->BackRightAlpha;
+ (*ctx->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;
+ }
}
- gl_read_rgba_span( ctx, width, srcx, sy, rgba );
+ gl_read_rgba_span( ctx, ctx->ReadBuffer, width, srcx, sy, rgba );
+ }
+
+ if (changeBuffer) {
+ /* read from the draw buffer again (in case of blending) */
+ (*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer,
+ ctx->Color.DriverDrawBuffer );
+ ctx->ReadBuffer->Alpha = saveReadAlpha;
}
+
if (ctx->Pixel.ScaleOrBiasRGBA) {
gl_scale_and_bias_rgba( ctx, width, rgba );
}
if (ctx->Pixel.MapColorFlag) {
gl_map_rgba( ctx, width, rgba );
}
- if (quick_draw && dy>=0 && dy<ctx->Buffer->Height) {
+ if (quick_draw && dy >= 0 && dy < ctx->DrawBuffer->Height) {
(*ctx->Driver.WriteRGBASpan)( ctx, width, destx, dy,
(const GLubyte (*)[4])rgba, NULL );
-
}
else if (zoom) {
gl_write_zoomed_rgba_span( ctx, width, destx, dy, zspan,
@@ -192,17 +207,12 @@ static void copy_rgba_pixels( GLcontext* ctx,
}
}
- if (needbuffer)
+ if (overlapping)
FREE(prgba);
-
- /* Restore current alpha buffer pointer */
- ctx->Buffer->Alpha = saveAlpha;
- if (changeBuffer)
- (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DriverDrawBuffer );
}
-static void copy_ci_pixels( GLcontext* ctx,
+static void copy_ci_pixels( GLcontext *ctx,
GLint srcx, GLint srcy, GLint width, GLint height,
GLint destx, GLint desty )
{
@@ -211,9 +221,9 @@ static void copy_ci_pixels( GLcontext* ctx,
GLint sy, dy, stepy;
GLint i, j;
GLboolean changeBuffer;
- const GLboolean zoom = ctx->Pixel.ZoomX!=1.0F || ctx->Pixel.ZoomY!=1.0F;
+ const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
const GLboolean shift_or_offset = ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset;
- GLboolean needbuffer;
+ GLint overlapping;
/* Determine if copy should be bottom-to-top or top-to-bottom */
if (srcy<desty) {
@@ -229,8 +239,8 @@ static void copy_ci_pixels( GLcontext* ctx,
stepy = 1;
}
- needbuffer = regions_overlap(srcx, srcy, destx, desty, width, height,
- ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
+ 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 */
@@ -241,9 +251,10 @@ static void copy_ci_pixels( GLcontext* ctx,
}
/* If read and draw buffer are different we must do buffer switching */
- changeBuffer = ctx->Pixel.ReadBuffer!=ctx->Color.DrawBuffer;
+ changeBuffer = ctx->Pixel.ReadBuffer != ctx->Color.DrawBuffer
+ || ctx->DrawBuffer != ctx->ReadBuffer;
- if (needbuffer) {
+ if (overlapping) {
GLint ssy = sy;
pci = (GLuint *) MALLOC(width * height * sizeof(GLuint));
if (!pci) {
@@ -252,26 +263,38 @@ static void copy_ci_pixels( GLcontext* ctx,
}
p = pci;
if (changeBuffer) {
- (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.DriverReadBuffer );
+ (*ctx->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
+ ctx->Pixel.DriverReadBuffer );
}
- for (j=0; j<height; j++, ssy+=stepy) {
- gl_read_index_span( ctx, width, srcx, ssy, p );
+ for (j = 0; j < height; j++, ssy += stepy) {
+ gl_read_index_span( ctx, ctx->ReadBuffer, width, srcx, ssy, p );
p += width;
}
p = pci;
}
+ else {
+ pci = NULL; /* silence compiler warning */
+ p = NULL;
+ }
- for (j=0; j<height; j++, sy+=stepy, dy+=stepy) {
+ for (j = 0; j < height; j++, sy += stepy, dy += stepy) {
GLuint indexes[MAX_WIDTH];
- if (needbuffer) {
+ if (overlapping) {
MEMCPY(indexes, p, width * sizeof(GLuint));
p += width;
}
else {
if (changeBuffer) {
- (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.DriverReadBuffer );
+ (*ctx->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
+ ctx->Pixel.DriverReadBuffer );
}
- gl_read_index_span( ctx, width, srcx, sy, indexes );
+ gl_read_index_span( ctx, ctx->ReadBuffer, width, srcx, sy, indexes );
+ }
+
+ if (changeBuffer) {
+ /* set read buffer back to draw buffer (in case of logicops) */
+ (*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer,
+ ctx->Color.DriverDrawBuffer );
}
if (shift_or_offset) {
@@ -281,22 +304,16 @@ static void copy_ci_pixels( GLcontext* ctx,
gl_map_ci( ctx, width, indexes );
}
- if (changeBuffer) {
- (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DrawBuffer );
- }
if (zoom) {
gl_write_zoomed_index_span( ctx, width, destx, dy, zspan, indexes, desty );
}
else {
- gl_write_index_span( ctx, width, destx, dy, zspan, indexes, GL_BITMAP );
+ gl_write_index_span(ctx, width, destx, dy, zspan, indexes, GL_BITMAP);
}
}
- if (needbuffer)
+ if (overlapping)
FREE(pci);
-
- if (changeBuffer)
- (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DriverDrawBuffer );
}
@@ -304,7 +321,7 @@ static void copy_ci_pixels( GLcontext* ctx,
/*
* TODO: Optimize!!!!
*/
-static void copy_depth_pixels( GLcontext* ctx, GLint srcx, GLint srcy,
+static void copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
GLint width, GLint height,
GLint destx, GLint desty )
{
@@ -315,10 +332,10 @@ static void copy_depth_pixels( GLcontext* ctx, GLint srcx, GLint srcy,
GLubyte rgba[MAX_WIDTH][4];
GLint sy, dy, stepy;
GLint i, j;
- const GLboolean zoom = ctx->Pixel.ZoomX!=1.0F || ctx->Pixel.ZoomY!=1.0F;
- GLboolean needbuffer;
+ const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
+ GLint overlapping;
- if (!ctx->Buffer->Depth) {
+ if (!ctx->ReadBuffer->Depth || !ctx->DrawBuffer->Depth) {
gl_error( ctx, GL_INVALID_OPERATION, "glCopyPixels" );
return;
}
@@ -337,25 +354,24 @@ static void copy_depth_pixels( GLcontext* ctx, GLint srcx, GLint srcy,
stepy = 1;
}
-
- needbuffer = regions_overlap(srcx, srcy, destx, desty, width, height,
- ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
+ 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.ByteColor );
- for (i=0; i<width; i++) {
+ for (i = 0; i < width; i++) {
rgba32[i] = color;
}
}
else {
- for (i=0;i<width;i++) {
+ for (i = 0; i < width; i++) {
indexes[i] = ctx->Current.Index;
}
}
- if (needbuffer) {
+ if (overlapping) {
GLint ssy = sy;
pdepth = (GLfloat *) MALLOC(width * height * sizeof(GLfloat));
if (!pdepth) {
@@ -363,23 +379,27 @@ static void copy_depth_pixels( GLcontext* ctx, GLint srcx, GLint srcy,
return;
}
p = pdepth;
- for (j=0; j<height; j++, ssy+=stepy) {
- (*ctx->Driver.ReadDepthSpanFloat)( ctx, width, srcx, ssy, p );
+ for (j = 0; j < height; j++, ssy += stepy) {
+ gl_read_depth_span_float(ctx, width, srcx, ssy, p);
p += width;
}
p = pdepth;
}
+ else {
+ pdepth = NULL; /* silence compiler warning */
+ p = NULL;
+ }
- for (j=0; j<height; j++, sy+=stepy, dy+=stepy) {
- if (needbuffer) {
+ for (j = 0; j < height; j++, sy += stepy, dy += stepy) {
+ if (overlapping) {
MEMCPY(depth, p, width * sizeof(GLfloat));
p += width;
}
else {
- (*ctx->Driver.ReadDepthSpanFloat)( ctx, width, srcx, sy, depth );
+ gl_read_depth_span_float(ctx, width, srcx, sy, depth);
}
- for (i=0;i<width;i++) {
+ for (i = 0; i < width; i++) {
GLfloat d = depth[i] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias;
zspan[i] = (GLint) (CLAMP( d, 0.0F, 1.0F ) * DEPTH_SCALE);
}
@@ -405,30 +425,30 @@ static void copy_depth_pixels( GLcontext* ctx, GLint srcx, GLint srcy,
}
}
- if (needbuffer)
+ if (overlapping)
FREE(pdepth);
}
-static void copy_stencil_pixels( GLcontext* ctx, GLint srcx, GLint srcy,
+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;
- GLstencil *p,*psten;
- const GLboolean zoom = (ctx->Pixel.ZoomX!=1.0F || ctx->Pixel.ZoomY!=1.0F);
- const GLboolean shift_or_offset = ctx->Pixel.IndexShift!=0 || ctx->Pixel.IndexOffset!=0;
- GLboolean needbuffer;
+ GLstencil *p, *psten;
+ 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;
- if (!ctx->Buffer->Stencil) {
+ if (!ctx->DrawBuffer->Stencil || !ctx->ReadBuffer->Stencil) {
gl_error( ctx, GL_INVALID_OPERATION, "glCopyPixels" );
return;
}
/* Determine if copy should be bottom-to-top or top-to-bottom */
- if (srcy<desty) {
+ if (srcy < desty) {
/* top-down max-to-min */
sy = srcy + height - 1;
dy = desty + height - 1;
@@ -441,10 +461,10 @@ static void copy_stencil_pixels( GLcontext* ctx, GLint srcx, GLint srcy,
stepy = 1;
}
- needbuffer = regions_overlap(srcx, srcy, destx, desty, width, height,
- ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
+ overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
+ ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
- if (needbuffer) {
+ if (overlapping) {
GLint ssy = sy;
psten = (GLstencil *) MALLOC(width * height * sizeof(GLstencil));
if (!psten) {
@@ -452,17 +472,21 @@ static void copy_stencil_pixels( GLcontext* ctx, GLint srcx, GLint srcy,
return;
}
p = psten;
- for (j=0; j<height; j++, ssy+=stepy) {
+ for (j = 0; j < height; j++, ssy += stepy) {
gl_read_stencil_span( ctx, width, srcx, ssy, p );
p += width;
}
p = psten;
}
+ else {
+ psten = NULL; /* silence compiler warning */
+ p = NULL;
+ }
- for (j=0; j<height; j++, sy+=stepy, dy+=stepy) {
+ for (j = 0; j < height; j++, sy += stepy, dy += stepy) {
GLstencil stencil[MAX_WIDTH];
- if (needbuffer) {
+ if (overlapping) {
MEMCPY(stencil, p, width * sizeof(GLstencil));
p += width;
}
@@ -485,21 +509,23 @@ static void copy_stencil_pixels( GLcontext* ctx, GLint srcx, GLint srcy,
}
}
- if (needbuffer)
+ if (overlapping)
FREE(psten);
}
-void gl_CopyPixels( GLcontext* ctx, GLint srcx, GLint srcy,
- GLsizei width, GLsizei height, GLenum type )
+void
+_mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height,
+ GLenum type )
{
+ GET_CURRENT_CONTEXT(ctx);
GLint destx, desty;
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCopyPixels");
- if (width<0 || height<0) {
+ if (width < 0 || height < 0) {
gl_error( ctx, GL_INVALID_VALUE, "glCopyPixels" );
return;
}
@@ -516,23 +542,23 @@ void gl_CopyPixels( GLcontext* ctx, GLint srcx, GLint srcy,
destx = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
desty = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
- if (type==GL_COLOR && ctx->Visual->RGBAflag) {
+ if (type == GL_COLOR && ctx->Visual->RGBAflag) {
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->RGBAflag) {
copy_ci_pixels( ctx, srcx, srcy, width, height, destx, desty );
}
- else if (type==GL_DEPTH) {
+ else if (type == GL_DEPTH) {
copy_depth_pixels( ctx, srcx, srcy, width, height, destx, desty );
}
- else if (type==GL_STENCIL) {
+ else if (type == GL_STENCIL) {
copy_stencil_pixels( ctx, srcx, srcy, width, height, destx, desty );
}
else {
gl_error( ctx, GL_INVALID_ENUM, "glCopyPixels" );
}
}
- else if (ctx->RenderMode==GL_FEEDBACK) {
+ else if (ctx->RenderMode == GL_FEEDBACK) {
GLfloat color[4];
UBYTE_RGBA_TO_FLOAT_RGBA(color, ctx->Current.ByteColor );
FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_COPY_PIXEL_TOKEN );
@@ -540,7 +566,7 @@ void gl_CopyPixels( GLcontext* ctx, GLint srcx, GLint srcy,
color, ctx->Current.Index,
ctx->Current.Texcoord[0] );
}
- else if (ctx->RenderMode==GL_SELECT) {
+ else if (ctx->RenderMode == GL_SELECT) {
gl_update_hitflag( ctx, ctx->Current.RasterPos[2] );
}