From 76e778dce59aa6f290db50242df945943fc47b05 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 12 Oct 2006 23:17:02 +0000 Subject: Lots of changes to support runtime renderbuffer depths. _swrast_read_rgba_span() now takes a datatype parameter. New optimization for glReadPixels(format=GL_RGB). New glCopyPixels optimization for the simple, common cases. --- src/mesa/swrast/s_drawpix.c | 149 ++++++++++++++++++++++---------------------- 1 file changed, 73 insertions(+), 76 deletions(-) (limited to 'src/mesa/swrast/s_drawpix.c') diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c index 5be2934b40..46dd797023 100644 --- a/src/mesa/swrast/s_drawpix.c +++ b/src/mesa/swrast/s_drawpix.c @@ -40,16 +40,17 @@ #include "s_zoom.h" + /** * 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 struct gl_pixelstore_attrib *userUnpack, - const GLvoid *pixels) +fast_draw_rgba_pixels(GLcontext *ctx, GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *userUnpack, + const GLvoid *pixels) { const GLint imgX = x, imgY = y; struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0]; @@ -63,7 +64,6 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y, if ((swrast->_RasterMask & ~CLIP_BIT) || ctx->Texture._EnabledCoordUnits || - userUnpack->Alignment != 1 || userUnpack->SwapBytes || ctx->_ImageTransferState) { /* can't handle any of those conditions */ @@ -100,26 +100,25 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y, else { /* non-simple zooming */ simpleZoom = GL_FALSE; + yStep = 1; if (unpack.RowLength == 0) unpack.RowLength = width; } /* * 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 "unpack.SkipRows" rows and skip "unpack.SkipPixels" pixels/row. */ - if (format == GL_RGBA && type == CHAN_TYPE && rbType == CHAN_TYPE) { - const GLchan *src = (const GLchan *) pixels - + (unpack.SkipRows * unpack.RowLength + unpack.SkipPixels) * 4; + if (format == GL_RGBA && type == rbType) { + const GLubyte *src = _mesa_image_address2d(&unpack, pixels, width, + height, format, type, 0, 0); + const GLint srcStride = _mesa_image_row_stride(&unpack, width, + format, type); if (simpleZoom) { GLint row; for (row = 0; row < drawHeight; row++) { rb->PutRow(ctx, rb, drawWidth, destX, destY, src, NULL); - src += unpack.RowLength * 4; + src += srcStride; destY += yStep; } } @@ -130,21 +129,25 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y, span.x = destX; span.y = destY + row; span.end = drawWidth; + span.array->ChanType = rbType; _swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span, src); - src += unpack.RowLength * 4; + src += srcStride; } + span.array->ChanType = CHAN_TYPE; } return GL_TRUE; } - if (format == GL_RGB && type == CHAN_TYPE && rbType == CHAN_TYPE) { - const GLchan *src = (const GLchan *) pixels - + (unpack.SkipRows * unpack.RowLength + unpack.SkipPixels) * 3; + if (format == GL_RGB && type == rbType) { + const GLubyte *src = _mesa_image_address2d(&unpack, pixels, width, + height, format, type, 0, 0); + const GLint srcStride = _mesa_image_row_stride(&unpack, width, + format, type); if (simpleZoom) { GLint row; for (row = 0; row < drawHeight; row++) { rb->PutRowRGB(ctx, rb, drawWidth, destX, destY, src, NULL); - src += unpack.RowLength * 3; + src += srcStride; destY += yStep; } } @@ -155,14 +158,20 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y, span.x = destX; span.y = destY; span.end = drawWidth; + span.array->ChanType = rbType; _swrast_write_zoomed_rgb_span(ctx, imgX, imgY, &span, src); - src += unpack.RowLength * 3; - destY++; + src += srcStride; + destY++; } + span.array->ChanType = CHAN_TYPE; } return GL_TRUE; } + /* Remaining cases haven't been tested with alignment != 1 */ + if (userUnpack->Alignment != 1) + return GL_FALSE; + if (format == GL_LUMINANCE && type == CHAN_TYPE && rbType == CHAN_TYPE) { const GLchan *src = (const GLchan *) pixels + (unpack.SkipRows * unpack.RowLength + unpack.SkipPixels); @@ -530,7 +539,7 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y, -/* +/** * Draw RGBA image. */ static void @@ -542,19 +551,17 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, { SWcontext *swrast = SWRAST_CONTEXT(ctx); const GLint imgX = x, imgY = y; - struct gl_renderbuffer *rb = NULL; /* only used for quickDraw path */ const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; - GLboolean quickDraw; GLfloat *convImage = NULL; GLuint transferOps = ctx->_ImageTransferState; SWspan span; /* Try an optimized glDrawPixels first */ - if (fast_draw_pixels(ctx, x, y, width, height, format, type, unpack, pixels)) + if (fast_draw_rgba_pixels(ctx, x, y, width, height, format, type, + unpack, pixels)) return; INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA); - if (ctx->Depth.Test) _swrast_span_default_z(ctx, &span); if (swrast->_FogEnabled) @@ -562,21 +569,6 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, if (ctx->Texture._EnabledCoordUnits) _swrast_span_default_texcoords(ctx, &span); - if (swrast->_RasterMask == 0 && !zoom && x >= 0 && y >= 0 - && x + width <= (GLint) ctx->DrawBuffer->Width - && y + height <= (GLint) ctx->DrawBuffer->Height - && ctx->DrawBuffer->_NumColorDrawBuffers[0] == 1) { - rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0]; - if (rb->DataType == format) - quickDraw = GL_TRUE; - else - quickDraw = GL_FALSE; - } - else { - quickDraw = GL_FALSE; - rb = NULL; - } - if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) { /* Convolution has to be handled specially. We'll create an * intermediate image, applying all pixel transfer operations @@ -628,6 +620,13 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, transferOps &= IMAGE_POST_CONVOLUTION_BITS; } + if (ctx->DrawBuffer->_NumColorDrawBuffers[0] > 0 && + ctx->DrawBuffer->_ColorDrawBuffers[0][0]->DataType != GL_FLOAT && + ctx->Color.ClampFragmentColor != GL_FALSE) { + /* need to clamp colors before applying fragment ops */ + transferOps |= IMAGE_CLAMP_BIT; + } + /* * General solution */ @@ -636,53 +635,51 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, || (ctx->Pixel.HistogramEnabled && ctx->Histogram.Sink); const GLbitfield interpMask = span.interpMask; const GLbitfield arrayMask = span.arrayMask; + const GLint srcStride + = _mesa_image_row_stride(unpack, width, format, type); GLint skipPixels = 0; + /* use span array for temp color storage */ + GLfloat *rgba = (GLfloat *) span.array->color.sz4.rgba; /* if the span is wider than MAX_WIDTH we have to do it in chunks */ while (skipPixels < width) { const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH); + const GLubyte *source = _mesa_image_address2d(unpack, pixels, + width, height, format, type, 0, skipPixels); GLint row; - ASSERT(span.end <= MAX_WIDTH); - for (row = 0; row < height; row++) { - const GLvoid *source = _mesa_image_address2d(unpack, - pixels, width, height, format, type, row, skipPixels); - - /* Set these for each row since the _swrast_write_* function may - * change them while clipping. - */ - span.array->ChanType = CHAN_TYPE; - span.x = x + skipPixels; - span.y = y + row; - span.end = spanWidth; - span.arrayMask = arrayMask; - span.interpMask = interpMask; - - _mesa_unpack_color_span_chan(ctx, spanWidth, GL_RGBA, - (GLchan *) span.array->rgba, - format, type, source, unpack, - transferOps); - - if (sink) - continue; - + /* get image row as float/RGBA */ + _mesa_unpack_color_span_float(ctx, spanWidth, GL_RGBA, rgba, + format, type, source, unpack, + transferOps); /* draw the span */ - if (quickDraw) { - rb->PutRow(ctx, rb, span.end, span.x, span.y, - span.array->rgba, NULL); - } - else if (zoom) { - _swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span, - span.array->rgba); - } - else { - _swrast_write_rgba_span(ctx, &span); + if (!sink) { + /* Set these for each row since the _swrast_write_* functions + * may change them while clipping/rendering. + */ + span.array->ChanType = GL_FLOAT; + span.x = x + skipPixels; + span.y = y + row; + span.end = spanWidth; + span.arrayMask = arrayMask; + span.interpMask = interpMask; + if (zoom) { + _swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span, rgba); + } + else { + _swrast_write_rgba_span(ctx, &span); + } } - } + + source += srcStride; + } /* for row */ skipPixels += spanWidth; - } + } /* while skipPixels < width */ + + /* XXX this is ugly/temporary, to undo above change */ + span.array->ChanType = CHAN_TYPE; } if (convImage) { -- cgit v1.2.3