diff options
Diffstat (limited to 'xc/extras/Mesa/src/copypix.c')
-rw-r--r-- | xc/extras/Mesa/src/copypix.c | 256 |
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] ); } |