From 46e8a513837ae8af03c2e69bf81dba5ae80eebfe Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 21 Aug 2000 14:24:10 +0000 Subject: basic glDrawPixels convolution implemented --- src/mesa/main/drawpix.c | 129 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 102 insertions(+), 27 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c index 02d618fc2d..3cf40956ab 100644 --- a/src/mesa/main/drawpix.c +++ b/src/mesa/main/drawpix.c @@ -1,8 +1,8 @@ -/* $Id: drawpix.c,v 1.28 2000/08/16 20:51:53 brianp Exp $ */ +/* $Id: drawpix.c,v 1.29 2000/08/21 14:24:10 brianp Exp $ */ /* * Mesa 3-D graphics library - * Version: 3.4 + * Version: 3.5 * * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. * @@ -30,6 +30,7 @@ #else #include "glheader.h" #include "context.h" +#include "convolve.h" #include "drawpix.h" #include "feedback.h" #include "image.h" @@ -99,10 +100,21 @@ _mesa_clip_pixelrect(const GLcontext *ctx, * Return: GL_TRUE if success, GL_FALSE if slow path must be used instead */ static GLboolean -simple_DrawPixels( GLcontext *ctx, GLint x, GLint y, - GLsizei width, GLsizei height, GLenum format, GLenum type, - const GLvoid *pixels ) +fast_draw_pixels(GLcontext *ctx, GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, const GLvoid *pixels) { + const GLuint cantTransferBits = + IMAGE_SCALE_BIAS_BIT | + IMAGE_SHIFT_OFFSET_BIT | + IMAGE_MAP_COLOR_BIT | + IMAGE_COLOR_TABLE_BIT | + IMAGE_CONVOLUTION_BIT | + IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT | + IMAGE_COLOR_MATRIX_BIT | + IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT | + IMAGE_HISTOGRAM_BIT | + IMAGE_MIN_MAX_BIT; const struct gl_pixelstore_attrib *unpack = &ctx->Unpack; GLubyte rgb[MAX_WIDTH][3]; GLubyte rgba[MAX_WIDTH][4]; @@ -112,23 +124,13 @@ simple_DrawPixels( GLcontext *ctx, GLint x, GLint y, if (!ctx->Current.RasterPosValid) { - /* no-op */ - return GL_TRUE; + return GL_TRUE; /* no-op */ } if ((ctx->RasterMask&(~(SCISSOR_BIT|WINCLIP_BIT)))==0 - && !ctx->Pixel.ScaleOrBiasRGBA - && !ctx->Pixel.ScaleOrBiasRGBApcm - && ctx->ColorMatrix.type == MATRIX_IDENTITY - && !ctx->Pixel.ColorTableEnabled - && !ctx->Pixel.PostColorMatrixColorTableEnabled - && !ctx->Pixel.PostConvolutionColorTableEnabled - && !ctx->Pixel.MinMaxEnabled - && !ctx->Pixel.HistogramEnabled - && ctx->Pixel.IndexShift==0 && ctx->Pixel.IndexOffset==0 - && ctx->Pixel.MapColorFlag==0 + && (ctx->ImageTransferState & cantTransferBits) == 0 && ctx->Texture.ReallyEnabled == 0 - && unpack->Alignment==1 + && unpack->Alignment == 1 && !unpack->SwapBytes && !unpack->LsbFirst) { @@ -525,7 +527,8 @@ draw_index_pixels( GLcontext *ctx, GLint x, GLint y, 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, GL_TRUE); + type, source, &ctx->Unpack, + ctx->ImageTransferState); if (zoom) { gl_write_zoomed_index_span(ctx, drawWidth, x, y, zspan, indexes, desty); } @@ -547,7 +550,6 @@ draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y, GLenum type, const GLvoid *pixels ) { const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; - const GLboolean shift_or_offset = ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset; const GLint desty = y; GLint row, drawWidth; @@ -572,8 +574,9 @@ draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y, 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, GL_FALSE); - if (shift_or_offset) { + 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) { @@ -671,7 +674,7 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y, 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, GL_TRUE ); + &ctx->Unpack, ctx->ImageTransferState ); if (ctx->Visual->RGBAflag) { if (zoom) { gl_write_zoomed_rgba_span(ctx, width, x, y, zspan, @@ -709,9 +712,11 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, const GLint desty = y; GLdepth zspan[MAX_WIDTH]; GLboolean quickDraw; + GLfloat *convImage = NULL; + GLuint transferOps = ctx->ImageTransferState; /* Try an optimized glDrawPixels first */ - if (simple_DrawPixels(ctx, x, y, width, height, format, type, pixels)) + if (fast_draw_pixels(ctx, x, y, width, height, format, type, pixels)) return; /* Fragment depth values */ @@ -725,8 +730,7 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, } - if (ctx->RasterMask == 0 && !zoom - && x >= 0 && y >= 0 + if (ctx->RasterMask == 0 && !zoom && x >= 0 && y >= 0 && x + width <= ctx->DrawBuffer->Width && y + height <= ctx->DrawBuffer->Height) { quickDraw = GL_TRUE; @@ -735,6 +739,69 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, quickDraw = GL_FALSE; } + if (ctx->ImageTransferState & IMAGE_CONVOLUTION_BIT) { + /* 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. + */ + const GLuint preConvTransferOps = + IMAGE_SCALE_BIAS_BIT | + IMAGE_SHIFT_OFFSET_BIT | + IMAGE_MAP_COLOR_BIT | + IMAGE_COLOR_TABLE_BIT; + const GLuint postConvTransferOps = + IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT | + IMAGE_COLOR_MATRIX_BIT | + IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT | + IMAGE_HISTOGRAM_BIT | + IMAGE_MIN_MAX_BIT; + 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 & preConvTransferOps, + GL_FALSE); + dest += width * 4; + } + + /* do convolution */ + if (ctx->Pixel.Convolution2DEnabled) { + _mesa_convolve_2d_image(ctx, &width, &height, tmpImage, convImage); + } + else if (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 &= postConvTransferOps; + } + /* * General solution */ @@ -747,7 +814,8 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, const GLvoid *source = _mesa_image_address(unpack, pixels, width, height, format, type, 0, row, 0); _mesa_unpack_ubyte_color_span(ctx, width, GL_RGBA, (void*) rgba, - format, type, source, unpack, GL_TRUE); + format, type, source, unpack, + transferOps); if ((ctx->Pixel.MinMaxEnabled && ctx->MinMax.Sink) || (ctx->Pixel.HistogramEnabled && ctx->Histogram.Sink)) continue; @@ -781,6 +849,10 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, } } } + + if (convImage) { + FREE(convImage); + } } @@ -805,6 +877,9 @@ _mesa_DrawPixels( GLsizei width, GLsizei height, gl_update_state(ctx); } + if (ctx->ImageTransferState == UPDATE_IMAGE_TRANSFER_STATE) + _mesa_update_image_transfer_state(ctx); + x = (GLint) (ctx->Current.RasterPos[0] + 0.5F); y = (GLint) (ctx->Current.RasterPos[1] + 0.5F); -- cgit v1.2.3