diff options
Diffstat (limited to 'src/mesa/main/drawpix.c')
-rw-r--r-- | src/mesa/main/drawpix.c | 844 |
1 files changed, 8 insertions, 836 deletions
diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c index 3e030ede61a..afdc5952734 100644 --- a/src/mesa/main/drawpix.c +++ b/src/mesa/main/drawpix.c @@ -1,4 +1,4 @@ -/* $Id: drawpix.c,v 1.43 2000/10/30 16:32:43 brianp Exp $ */ +/* $Id: drawpix.c,v 1.44 2000/10/31 18:09:44 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -31,819 +31,17 @@ #include "glheader.h" #include "colormac.h" #include "context.h" -#include "convolve.h" -#include "drawpix.h" #include "feedback.h" -#include "image.h" #include "macros.h" #include "mem.h" #include "mmath.h" -#include "pixel.h" -#include "pixeltex.h" -#include "span.h" #include "state.h" -#include "stencil.h" -#include "texture.h" #include "types.h" -#include "zoom.h" +#include "swrast/swrast.h" #endif -/* - * Given the dest position, size and skipPixels and skipRows values - * for a glDrawPixels command, perform clipping of the image bounds - * so the result lies withing the context's buffer bounds. - * Return: GL_TRUE if image is ready for drawing - * GL_FALSE if image was completely clipped away (draw nothing) - */ -GLboolean -_mesa_clip_pixelrect(const GLcontext *ctx, - GLint *destX, GLint *destY, - GLsizei *width, GLsizei *height, - GLint *skipPixels, GLint *skipRows) -{ - const GLframebuffer *buffer = ctx->DrawBuffer; - - /* left clipping */ - if (*destX < buffer->Xmin) { - *skipPixels += (buffer->Xmin - *destX); - *width -= (buffer->Xmin - *destX); - *destX = buffer->Xmin; - } - /* right clipping */ - if (*destX + *width > buffer->Xmax) - *width -= (*destX + *width - buffer->Xmax); - - if (*width <= 0) - return GL_FALSE; - - /* bottom clipping */ - if (*destY < buffer->Ymin) { - *skipRows += (buffer->Ymin - *destY); - *height -= (buffer->Ymin - *destY); - *destY = buffer->Ymin; - } - /* top clipping */ - if (*destY + *height > buffer->Ymax) - *height -= (*destY + *height - buffer->Ymax); - - if (*height <= 0) - return GL_TRUE; - - return GL_TRUE; -} - - - -/* - * Try to do a fast and simple RGB(a) glDrawPixels. - * Return: GL_TRUE if success, GL_FALSE if slow path must be used instead - */ -static GLboolean -fast_draw_pixels(GLcontext *ctx, GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, const GLvoid *pixels) -{ - const struct gl_pixelstore_attrib *unpack = &ctx->Unpack; - GLchan rgb[MAX_WIDTH][3]; - GLchan rgba[MAX_WIDTH][4]; - - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, "glDrawPixels", - GL_FALSE); - - - if (!ctx->Current.RasterPosValid) { - return GL_TRUE; /* no-op */ - } - - if ((ctx->RasterMask&(~(SCISSOR_BIT|WINCLIP_BIT)))==0 - && ctx->Texture.ReallyEnabled == 0 - && unpack->Alignment == 1 - && !unpack->SwapBytes - && !unpack->LsbFirst) { - - GLint destX = x; - GLint destY = y; - GLint drawWidth = width; /* actual width drawn */ - GLint drawHeight = height; /* actual height drawn */ - GLint skipPixels = unpack->SkipPixels; - GLint skipRows = unpack->SkipRows; - GLint rowLength; - GLdepth zSpan[MAX_WIDTH]; /* only used when zooming */ - GLint zoomY0 = 0; - - if (unpack->RowLength > 0) - rowLength = unpack->RowLength; - else - rowLength = width; - - /* If we're not using pixel zoom then do all clipping calculations - * now. Otherwise, we'll let the gl_write_zoomed_*_span() functions - * handle the clipping. - */ - if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { - /* horizontal clipping */ - if (destX < ctx->DrawBuffer->Xmin) { - skipPixels += (ctx->DrawBuffer->Xmin - destX); - drawWidth -= (ctx->DrawBuffer->Xmin - destX); - destX = ctx->DrawBuffer->Xmin; - } - if (destX + drawWidth > ctx->DrawBuffer->Xmax) - drawWidth -= (destX + drawWidth - ctx->DrawBuffer->Xmax); - if (drawWidth <= 0) - return GL_TRUE; - - /* vertical clipping */ - if (destY < ctx->DrawBuffer->Ymin) { - skipRows += (ctx->DrawBuffer->Ymin - destY); - drawHeight -= (ctx->DrawBuffer->Ymin - destY); - destY = ctx->DrawBuffer->Ymin; - } - if (destY + drawHeight > ctx->DrawBuffer->Ymax) - drawHeight -= (destY + drawHeight - ctx->DrawBuffer->Ymax); - if (drawHeight <= 0) - return GL_TRUE; - } - else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) { - /* upside-down image */ - /* horizontal clipping */ - if (destX < ctx->DrawBuffer->Xmin) { - skipPixels += (ctx->DrawBuffer->Xmin - destX); - drawWidth -= (ctx->DrawBuffer->Xmin - destX); - destX = ctx->DrawBuffer->Xmin; - } - if (destX + drawWidth > ctx->DrawBuffer->Xmax) - drawWidth -= (destX + drawWidth - ctx->DrawBuffer->Xmax); - if (drawWidth <= 0) - return GL_TRUE; - - /* vertical clipping */ - if (destY > ctx->DrawBuffer->Ymax) { - skipRows += (destY - ctx->DrawBuffer->Ymax); - drawHeight -= (destY - ctx->DrawBuffer->Ymax); - destY = ctx->DrawBuffer->Ymax; - } - if (destY - drawHeight < ctx->DrawBuffer->Ymin) - drawHeight -= (ctx->DrawBuffer->Ymin - (destY - drawHeight)); - if (drawHeight <= 0) - return GL_TRUE; - } - else { - /* setup array of fragment Z value to pass to zoom function */ - GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->Visual.DepthMaxF); - GLint i; - ASSERT(drawWidth < MAX_WIDTH); - for (i=0; i<drawWidth; i++) - zSpan[i] = z; - - /* save Y value of first row */ - zoomY0 = (GLint) (ctx->Current.RasterPos[1] + 0.5F); - } - - - /* - * Ready to draw! - * The window region at (destX, destY) of size (drawWidth, drawHeight) - * will be written to. - * We'll take pixel data from buffer pointed to by "pixels" but we'll - * skip "skipRows" rows and skip "skipPixels" pixels/row. - */ - - if (format == GL_RGBA && type == CHAN_TYPE - && ctx->ImageTransferState==0) { - if (ctx->Visual.RGBAflag) { - GLchan *src = (GLchan *) pixels - + (skipRows * rowLength + skipPixels) * 4; - if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { - /* no zooming */ - GLint row; - for (row=0; row<drawHeight; row++) { - (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY, - (void *) src, NULL); - src += rowLength * 4; - destY++; - } - } - else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) { - /* upside-down */ - GLint row; - for (row=0; row<drawHeight; row++) { - destY--; - (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY, - (void *) src, NULL); - src += rowLength * 4; - } - } - else { - /* with zooming */ - GLint row; - for (row=0; row<drawHeight; row++) { - gl_write_zoomed_rgba_span(ctx, drawWidth, destX, destY, - zSpan, 0, (void *) src, zoomY0); - src += rowLength * 4; - destY++; - } - } - } - return GL_TRUE; - } - else if (format == GL_RGB && type == CHAN_TYPE - && ctx->ImageTransferState == 0) { - if (ctx->Visual.RGBAflag) { - GLchan *src = (GLchan *) pixels - + (skipRows * rowLength + skipPixels) * 3; - if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { - GLint row; - for (row=0; row<drawHeight; row++) { - (*ctx->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY, - (void *) src, NULL); - src += rowLength * 3; - destY++; - } - } - else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) { - /* upside-down */ - GLint row; - for (row=0; row<drawHeight; row++) { - destY--; - (*ctx->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY, - (void *) src, NULL); - src += rowLength * 3; - } - } - else { - /* with zooming */ - GLint row; - for (row=0; row<drawHeight; row++) { - gl_write_zoomed_rgb_span(ctx, drawWidth, destX, destY, - zSpan, 0, (void *) src, zoomY0); - src += rowLength * 3; - destY++; - } - } - } - return GL_TRUE; - } - else if (format == GL_LUMINANCE && type == CHAN_TYPE - && ctx->ImageTransferState==0) { - if (ctx->Visual.RGBAflag) { - GLchan *src = (GLchan *) pixels - + (skipRows * rowLength + skipPixels); - if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { - /* no zooming */ - GLint row; - ASSERT(drawWidth < MAX_WIDTH); - for (row=0; row<drawHeight; row++) { - GLint i; - for (i=0;i<drawWidth;i++) { - rgb[i][0] = src[i]; - rgb[i][1] = src[i]; - rgb[i][2] = src[i]; - } - (*ctx->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY, - (void *) rgb, NULL); - src += rowLength; - destY++; - } - } - else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) { - /* upside-down */ - GLint row; - ASSERT(drawWidth < MAX_WIDTH); - for (row=0; row<drawHeight; row++) { - GLint i; - for (i=0;i<drawWidth;i++) { - rgb[i][0] = src[i]; - rgb[i][1] = src[i]; - rgb[i][2] = src[i]; - } - destY--; - (*ctx->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY, - (void *) rgb, NULL); - src += rowLength; - } - } - else { - /* with zooming */ - GLint row; - ASSERT(drawWidth < MAX_WIDTH); - for (row=0; row<drawHeight; row++) { - GLint i; - for (i=0;i<drawWidth;i++) { - rgb[i][0] = src[i]; - rgb[i][1] = src[i]; - rgb[i][2] = src[i]; - } - gl_write_zoomed_rgb_span(ctx, drawWidth, destX, destY, - zSpan, 0, (void *) rgb, zoomY0); - src += rowLength; - destY++; - } - } - } - return GL_TRUE; - } - else if (format == GL_LUMINANCE_ALPHA && type == CHAN_TYPE - && ctx->ImageTransferState == 0) { - if (ctx->Visual.RGBAflag) { - GLchan *src = (GLchan *) pixels - + (skipRows * rowLength + skipPixels)*2; - if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { - /* no zooming */ - GLint row; - ASSERT(drawWidth < MAX_WIDTH); - for (row=0; row<drawHeight; row++) { - GLint i; - GLchan *ptr = src; - for (i=0;i<drawWidth;i++) { - rgba[i][0] = *ptr; - rgba[i][1] = *ptr; - rgba[i][2] = *ptr++; - rgba[i][3] = *ptr++; - } - (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY, - (void *) rgba, NULL); - src += rowLength*2; - destY++; - } - } - else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) { - /* upside-down */ - GLint row; - ASSERT(drawWidth < MAX_WIDTH); - for (row=0; row<drawHeight; row++) { - GLint i; - GLchan *ptr = src; - for (i=0;i<drawWidth;i++) { - rgba[i][0] = *ptr; - rgba[i][1] = *ptr; - rgba[i][2] = *ptr++; - rgba[i][3] = *ptr++; - } - destY--; - (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY, - (void *) rgba, NULL); - src += rowLength*2; - } - } - else { - /* with zooming */ - GLint row; - ASSERT(drawWidth < MAX_WIDTH); - for (row=0; row<drawHeight; row++) { - GLchan *ptr = src; - GLint i; - for (i=0;i<drawWidth;i++) { - rgba[i][0] = *ptr; - rgba[i][1] = *ptr; - rgba[i][2] = *ptr++; - rgba[i][3] = *ptr++; - } - gl_write_zoomed_rgba_span(ctx, drawWidth, destX, destY, - zSpan, 0, (void *) rgba, zoomY0); - src += rowLength*2; - destY++; - } - } - } - return GL_TRUE; - } - else if (format==GL_COLOR_INDEX && type==GL_UNSIGNED_BYTE) { - GLubyte *src = (GLubyte *) pixels + skipRows * rowLength + skipPixels; - if (ctx->Visual.RGBAflag) { - /* convert CI data to RGBA */ - if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { - /* no zooming */ - GLint row; - for (row=0; row<drawHeight; row++) { - ASSERT(drawWidth < MAX_WIDTH); - _mesa_map_ci8_to_rgba(ctx, drawWidth, src, rgba); - (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY, - (const GLchan (*)[4]) rgba, - NULL); - src += rowLength; - destY++; - } - return GL_TRUE; - } - else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) { - /* upside-down */ - GLint row; - for (row=0; row<drawHeight; row++) { - ASSERT(drawWidth < MAX_WIDTH); - _mesa_map_ci8_to_rgba(ctx, drawWidth, src, rgba); - destY--; - (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY, - (const GLchan (*)[4]) rgba, - NULL); - src += rowLength; - } - return GL_TRUE; - } - else { - /* with zooming */ - GLint row; - for (row=0; row<drawHeight; row++) { - ASSERT(drawWidth < MAX_WIDTH); - _mesa_map_ci8_to_rgba(ctx, drawWidth, src, rgba); - gl_write_zoomed_rgba_span(ctx, drawWidth, destX, destY, - zSpan, 0, (void *) rgba, zoomY0); - src += rowLength; - destY++; - } - return GL_TRUE; - } - } - else if (ctx->ImageTransferState==0) { - /* write CI data to CI frame buffer */ - GLint row; - if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { - /* no zooming */ - for (row=0; row<drawHeight; row++) { - (*ctx->Driver.WriteCI8Span)(ctx, drawWidth, destX, destY, - src, NULL); - src += rowLength; - destY++; - } - return GL_TRUE; - } - else { - /* with zooming */ - return GL_FALSE; - } - } - } - else { - /* can't handle this pixel format and/or data type here */ - return GL_FALSE; - } - } - - /* can't do a simple draw, have to use slow path */ - return GL_FALSE; -} - - - -/* - * Do glDrawPixels of index pixels. - */ -static void -draw_index_pixels( GLcontext *ctx, GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum type, const GLvoid *pixels ) -{ - const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; - const GLint desty = y; - GLint row, drawWidth; - GLdepth zspan[MAX_WIDTH]; - - drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; - - /* Fragment depth values */ - if (ctx->Depth.Test || ctx->Fog.Enabled) { - GLdepth zval = (GLdepth) (ctx->Current.RasterPos[2] * ctx->Visual.DepthMaxF); - GLint i; - for (i = 0; i < drawWidth; i++) { - zspan[i] = zval; - } - } - - /* - * General solution - */ - for (row = 0; row < height; row++, y++) { - GLuint indexes[MAX_WIDTH]; - const GLvoid *source = _mesa_image_address(&ctx->Unpack, - pixels, width, height, GL_COLOR_INDEX, type, 0, row, 0); - _mesa_unpack_index_span(ctx, drawWidth, GL_UNSIGNED_INT, indexes, - type, source, &ctx->Unpack, - ctx->ImageTransferState); - if (zoom) { - gl_write_zoomed_index_span(ctx, drawWidth, x, y, zspan, 0, indexes, desty); - } - else { - gl_write_index_span(ctx, drawWidth, x, y, zspan, 0, indexes, GL_BITMAP); - } - } -} - - - -/* - * Do glDrawPixels of stencil image. The image datatype may either - * be GLubyte or GLbitmap. - */ -static void -draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum type, const GLvoid *pixels ) -{ - const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; - const GLint desty = y; - GLint row, drawWidth; - - if (type != GL_BYTE && - type != GL_UNSIGNED_BYTE && - type != GL_SHORT && - type != GL_UNSIGNED_SHORT && - type != GL_INT && - type != GL_UNSIGNED_INT && - type != GL_FLOAT && - type != GL_BITMAP) { - gl_error( ctx, GL_INVALID_ENUM, "glDrawPixels(stencil type)"); - return; - } - - drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; - - for (row = 0; row < height; row++, y++) { - GLstencil values[MAX_WIDTH]; - GLenum destType = (sizeof(GLstencil) == sizeof(GLubyte)) - ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT; - const GLvoid *source = _mesa_image_address(&ctx->Unpack, - pixels, width, height, GL_COLOR_INDEX, type, 0, row, 0); - _mesa_unpack_index_span(ctx, drawWidth, destType, values, - type, source, &ctx->Unpack, - ctx->ImageTransferState); - if (ctx->ImageTransferState & IMAGE_SHIFT_OFFSET_BIT) { - _mesa_shift_and_offset_stencil( ctx, drawWidth, values ); - } - if (ctx->Pixel.MapStencilFlag) { - _mesa_map_stencil( ctx, drawWidth, values ); - } - - if (zoom) { - gl_write_zoomed_stencil_span( ctx, (GLuint) drawWidth, x, y, - values, desty ); - } - else { - _mesa_write_stencil_span( ctx, (GLuint) drawWidth, x, y, values ); - } - } -} - - - -/* - * Do a glDrawPixels of depth values. - */ -static void -draw_depth_pixels( GLcontext *ctx, GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum type, const GLvoid *pixels ) -{ - const GLboolean bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0; - const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; - const GLint desty = y; - GLchan rgba[MAX_WIDTH][4]; - GLuint ispan[MAX_WIDTH]; - GLint drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; - - if (type != GL_BYTE - && type != GL_UNSIGNED_BYTE - && type != GL_SHORT - && type != GL_UNSIGNED_SHORT - && type != GL_INT - && type != GL_UNSIGNED_INT - && type != GL_FLOAT) { - gl_error(ctx, GL_INVALID_ENUM, "glDrawPixels(type)"); - return; - } - - /* Colors or indexes */ - if (ctx->Visual.RGBAflag) { - GLint r = FLOAT_TO_CHAN(ctx->Current.RasterColor[0]); - GLint g = FLOAT_TO_CHAN(ctx->Current.RasterColor[1]); - GLint b = FLOAT_TO_CHAN(ctx->Current.RasterColor[2]); - GLint a = FLOAT_TO_CHAN(ctx->Current.RasterColor[3]); - GLint i; - for (i = 0; i < drawWidth; i++) { - rgba[i][RCOMP] = r; - rgba[i][GCOMP] = g; - rgba[i][BCOMP] = b; - rgba[i][ACOMP] = a; - } - } - else { - GLint i; - for (i = 0; i < drawWidth; i++) { - ispan[i] = ctx->Current.RasterIndex; - } - } - - if (type==GL_UNSIGNED_SHORT && sizeof(GLdepth)==sizeof(GLushort) - && !bias_or_scale && !zoom && ctx->Visual.RGBAflag) { - /* Special case: directly write 16-bit depth values */ - GLint row; - for (row = 0; row < height; row++, y++) { - GLdepth zspan[MAX_WIDTH]; - const GLushort *zptr = _mesa_image_address(&ctx->Unpack, - pixels, width, height, GL_DEPTH_COMPONENT, type, 0, row, 0); - GLint i; - for (i = 0; i < width; i++) - zspan[i] = zptr[i]; - gl_write_rgba_span( ctx, width, x, y, zspan, 0, rgba, GL_BITMAP ); - } - } - else if (type==GL_UNSIGNED_INT && ctx->Visual.DepthBits == 32 - && !bias_or_scale && !zoom && ctx->Visual.RGBAflag) { - /* Special case: directly write 32-bit depth values */ - GLint row; - for (row = 0; row < height; row++, y++) { - const GLuint *zptr = _mesa_image_address(&ctx->Unpack, - pixels, width, height, GL_DEPTH_COMPONENT, type, 0, row, 0); - gl_write_rgba_span( ctx, width, x, y, zptr, 0, rgba, GL_BITMAP ); - } - } - else { - /* General case */ - GLint row; - for (row = 0; row < height; row++, y++) { - GLdepth zspan[MAX_WIDTH]; - const GLvoid *src = _mesa_image_address(&ctx->Unpack, - pixels, width, height, GL_DEPTH_COMPONENT, type, 0, row, 0); - _mesa_unpack_depth_span( ctx, drawWidth, zspan, type, src, - &ctx->Unpack, ctx->ImageTransferState ); - if (ctx->Visual.RGBAflag) { - if (zoom) { - gl_write_zoomed_rgba_span(ctx, width, x, y, zspan, 0, - (const GLchan (*)[4]) rgba, desty); - } - else { - gl_write_rgba_span(ctx, width, x, y, zspan, 0, rgba, GL_BITMAP); - } - } - else { - if (zoom) { - gl_write_zoomed_index_span(ctx, width, x, y, zspan, 0, - ispan, GL_BITMAP); - } - else { - gl_write_index_span(ctx, width, x, y, zspan, 0, - ispan, GL_BITMAP); - } - } - - } - } -} - - -/* - * Do glDrawPixels of RGBA pixels. - */ -static void -draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, const GLvoid *pixels ) -{ - const struct gl_pixelstore_attrib *unpack = &ctx->Unpack; - const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; - const GLint desty = y; - GLdepth zspan[MAX_WIDTH]; - GLboolean quickDraw; - GLfloat *convImage = NULL; - GLuint transferOps = ctx->ImageTransferState; - - if (!_mesa_is_legal_format_and_type(format, type)) { - gl_error(ctx, GL_INVALID_ENUM, "glDrawPixels(format or type)"); - return; - } - - /* Try an optimized glDrawPixels first */ - if (fast_draw_pixels(ctx, x, y, width, height, format, type, pixels)) - return; - - /* Fragment depth values */ - if (ctx->Depth.Test || ctx->Fog.Enabled) { - /* fill in array of z values */ - GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->Visual.DepthMaxF); - GLint i; - for (i=0;i<width;i++) { - zspan[i] = z; - } - } - - - if (ctx->RasterMask == 0 && !zoom && x >= 0 && y >= 0 - && x + width <= ctx->DrawBuffer->Width - && y + height <= ctx->DrawBuffer->Height) { - quickDraw = GL_TRUE; - } - else { - quickDraw = GL_FALSE; - } - - if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) { - /* Convolution has to be handled specially. We'll create an - * intermediate image, applying all pixel transfer operations - * up to convolution. Then we'll convolve the image. Then - * we'll proceed with the rest of the transfer operations and - * rasterize the image. - */ - GLint row; - GLfloat *dest, *tmpImage; - - tmpImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat)); - if (!tmpImage) { - gl_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); - return; - } - convImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat)); - if (!convImage) { - FREE(tmpImage); - gl_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); - return; - } - - /* Unpack the image and apply transfer ops up to convolution */ - dest = tmpImage; - for (row = 0; row < height; row++) { - const GLvoid *source = _mesa_image_address(unpack, - pixels, width, height, format, type, 0, row, 0); - _mesa_unpack_float_color_span(ctx, width, GL_RGBA, (void *) dest, - format, type, source, unpack, - transferOps & IMAGE_PRE_CONVOLUTION_BITS, - GL_FALSE); - dest += width * 4; - } - - /* do convolution */ - if (ctx->Pixel.Convolution2DEnabled) { - _mesa_convolve_2d_image(ctx, &width, &height, tmpImage, convImage); - } - else { - ASSERT(ctx->Pixel.Separable2DEnabled); - _mesa_convolve_sep_image(ctx, &width, &height, tmpImage, convImage); - } - FREE(tmpImage); - - /* continue transfer ops and draw the convolved image */ - unpack = &_mesa_native_packing; - pixels = convImage; - format = GL_RGBA; - type = GL_FLOAT; - transferOps &= IMAGE_POST_CONVOLUTION_BITS; - } - - /* - * General solution - */ - { - GLchan rgba[MAX_WIDTH][4]; - GLint row; - if (width > MAX_WIDTH) - width = MAX_WIDTH; - for (row = 0; row < height; row++, y++) { - const GLvoid *source = _mesa_image_address(unpack, - pixels, width, height, format, type, 0, row, 0); - _mesa_unpack_chan_color_span(ctx, width, GL_RGBA, (void*) rgba, - format, type, source, unpack, - transferOps); - if ((ctx->Pixel.MinMaxEnabled && ctx->MinMax.Sink) || - (ctx->Pixel.HistogramEnabled && ctx->Histogram.Sink)) - continue; - - 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 < ctx->Const.MaxTextureUnits; unit++) { - if (ctx->Texture.Unit[unit].ReallyEnabled) { - _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 (quickDraw) { - (*ctx->Driver.WriteRGBASpan)( ctx, width, x, y, - (CONST GLchan (*)[]) rgba, NULL); - } - else if (zoom) { - gl_write_zoomed_rgba_span( ctx, width, x, y, zspan, 0, - (CONST GLchan (*)[]) rgba, desty ); - } - else { - gl_write_rgba_span( ctx, (GLuint) width, x, y, zspan, 0, - rgba, GL_BITMAP); - } - } - } - - if (convImage) { - FREE(convImage); - } -} - /* @@ -872,42 +70,16 @@ _mesa_DrawPixels( GLsizei width, GLsizei height, ctx->OcclusionResult = GL_TRUE; /* see if device driver can do the drawpix */ + RENDER_START(ctx); + if (ctx->Driver.DrawPixels && (*ctx->Driver.DrawPixels)(ctx, x, y, width, height, format, type, &ctx->Unpack, pixels)) { - return; - } + /* finished */ + } else + _swrast_DrawPixels( ctx, x, y, width, height, format, type, + &ctx->Unpack, pixels ); - RENDER_START(ctx); - switch (format) { - case GL_STENCIL_INDEX: - draw_stencil_pixels( ctx, x, y, width, height, type, pixels ); - break; - case GL_DEPTH_COMPONENT: - draw_depth_pixels( ctx, x, y, width, height, type, pixels ); - break; - case GL_COLOR_INDEX: - if (ctx->Visual.RGBAflag) - draw_rgba_pixels(ctx, x,y, width, height, format, type, pixels); - else - draw_index_pixels(ctx, x, y, width, height, type, pixels); - break; - case GL_RED: - case GL_GREEN: - case GL_BLUE: - case GL_ALPHA: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - case GL_RGB: - case GL_BGR: - case GL_RGBA: - case GL_BGRA: - case GL_ABGR_EXT: - draw_rgba_pixels(ctx, x, y, width, height, format, type, pixels); - break; - default: - gl_error( ctx, GL_INVALID_ENUM, "glDrawPixels(format)" ); - } RENDER_FINISH(ctx); } else if (ctx->RenderMode==GL_FEEDBACK) { |