X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fdrawpix.c;h=12b9f2930d898dbfdc75ddd13cc841ac67f51e5a;hb=263581bba4d61291c54313648063a30c47106f0b;hp=4166596ed659633cae688057eb4a7084d59e881f;hpb=4b7526d001ee739ce4287e9110c9d6cd97738ba4;p=mesa.git diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c index 4166596ed65..12b9f2930d8 100644 --- a/src/mesa/main/drawpix.c +++ b/src/mesa/main/drawpix.c @@ -1,21 +1,20 @@ -/* $Id: drawpix.c,v 1.7 1999/11/18 15:44:37 brianp Exp $ */ /* * Mesa 3-D graphics library - * Version: 3.3 - * - * Copyright (C) 1999 Brian Paul All Rights Reserved. - * + * Version: 4.1 + * + * Copyright (C) 1999-2002 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"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -24,680 +23,266 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#ifdef PC_HEADER -#include "all.h" -#else #include "glheader.h" +#include "imports.h" +#include "colormac.h" #include "context.h" #include "drawpix.h" #include "feedback.h" -#include "image.h" #include "macros.h" -#include "mmath.h" -#include "pixel.h" -#include "span.h" -#include "stencil.h" -#include "types.h" -#include "zoom.h" -#endif - +#include "state.h" +#include "mtypes.h" +#if _HAVE_FULL_GL /* - * Try to do a fast and simple RGB(a) glDrawPixels. - * Return: GL_TRUE if success, GL_FALSE if slow path must be used instead + * Execute glDrawPixels */ -static GLboolean -simple_DrawPixels( GLcontext *ctx, GLint x, GLint y, - GLsizei width, GLsizei height, GLenum format, GLenum type, - const GLvoid *pixels ) +void GLAPIENTRY +_mesa_DrawPixels( GLsizei width, GLsizei height, + GLenum format, GLenum type, const GLvoid *pixels ) { - const struct gl_pixelstore_attrib *unpack = &ctx->Unpack; - GLubyte rgb[MAX_WIDTH][3]; - GLubyte rgba[MAX_WIDTH][4]; - - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, "glDrawPixels", - GL_FALSE); - - - if (!ctx->Current.RasterPosValid) { - /* no-op */ - return GL_TRUE; - } - - if (ctx->NewState) { - gl_update_state(ctx); - } + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - /* see if device driver can do the drawpix */ - if (ctx->Driver.DrawPixels - && (*ctx->Driver.DrawPixels)(ctx, x, y, width, height, format, type, - unpack, pixels)) { - return GL_TRUE; + if (width < 0 || height < 0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glDrawPixels(width or height < 0" ); + return; } - if ((ctx->RasterMask&(~(SCISSOR_BIT|WINCLIP_BIT)))==0 - && ctx->Pixel.RedBias==0.0 && ctx->Pixel.RedScale==1.0 - && ctx->Pixel.GreenBias==0.0 && ctx->Pixel.GreenScale==1.0 - && ctx->Pixel.BlueBias==0.0 && ctx->Pixel.BlueScale==1.0 - && ctx->Pixel.AlphaBias==0.0 && ctx->Pixel.AlphaScale==1.0 - && ctx->Pixel.IndexShift==0 && ctx->Pixel.IndexOffset==0 - && ctx->Pixel.MapColorFlag==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; - - 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->Buffer->Xmin) { - skipPixels += (ctx->Buffer->Xmin - destX); - drawWidth -= (ctx->Buffer->Xmin - destX); - destX = ctx->Buffer->Xmin; - } - if (destX + drawWidth > ctx->Buffer->Xmax) - drawWidth -= (destX + drawWidth - ctx->Buffer->Xmax - 1); - if (drawWidth <= 0) - return GL_TRUE; - - /* vertical clipping */ - if (destY < ctx->Buffer->Ymin) { - skipRows += (ctx->Buffer->Ymin - destY); - drawHeight -= (ctx->Buffer->Ymin - destY); - destY = ctx->Buffer->Ymin; - } - if (destY + drawHeight > ctx->Buffer->Ymax) - drawHeight -= (destY + drawHeight - ctx->Buffer->Ymax - 1); - if (drawHeight <= 0) - return GL_TRUE; - - zoomY0 = 0; /* not used - silence compiler warning */ + if (ctx->RenderMode==GL_RENDER) { + GLint x, y; + if (!pixels || !ctx->Current.RasterPosValid) { + return; } - else { - /* setup array of fragment Z value to pass to zoom function */ - GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * DEPTH_SCALE); - GLint i; - assert(drawWidth < MAX_WIDTH); - for (i=0; iCurrent.RasterPos[1] + 0.5F); + + if (ctx->NewState) { + _mesa_update_state(ctx); } + /* Round, to satisfy conformance tests (matches SGI's OpenGL) */ + x = IROUND(ctx->Current.RasterPos[0]); + y = IROUND(ctx->Current.RasterPos[1]); - /* - * 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==GL_UNSIGNED_BYTE) { - if (ctx->Visual->RGBAflag) { - GLubyte *src = (GLubyte *) pixels - + (skipRows * rowLength + skipPixels) * 4; - if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { - /* no zooming */ - GLint row; - for (row=0; rowDriver.WriteRGBASpan)(ctx, drawWidth, destX, destY, - (void *) src, NULL); - src += rowLength * 4; - destY++; - } - } - else { - /* with zooming */ - GLint row; - for (row=0; rowVisual->RGBAflag) { - GLubyte *src = (GLubyte *) pixels - + (skipRows * rowLength + skipPixels) * 3; - if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { - GLint row; - for (row=0; rowDriver.WriteRGBSpan)(ctx, drawWidth, destX, destY, - (void *) src, NULL); - src += rowLength * 3; - destY++; - } - } - else { - /* with zooming */ - GLint row; - for (row=0; rowVisual->RGBAflag) { - GLubyte *src = (GLubyte *) 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; rowDriver.WriteRGBSpan)(ctx, drawWidth, destX, destY, - (void *) rgb, NULL); - src += rowLength; - destY++; - } - } - else { - /* with zooming */ - GLint row; - assert(drawWidth < MAX_WIDTH); - for (row=0; rowVisual->RGBAflag) { - GLubyte *src = (GLubyte *) 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; rowDriver.WriteRGBASpan)(ctx, drawWidth, destX, destY, - (void *) rgba, NULL); - src += rowLength*2; - destY++; - } - } - else { - /* with zooming */ - GLint row; - assert(drawWidth < MAX_WIDTH); - for (row=0; rowVisual->RGBAflag) { - /* convert CI data to RGBA */ - if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { - /* no zooming */ - GLint row; - for (row=0; rowDriver.WriteRGBASpan)(ctx, drawWidth, destX, destY, - (const GLubyte (*)[4])rgba, - NULL); - src += rowLength; - destY++; - } - return GL_TRUE; - } - else { - /* with zooming */ - GLint row; - for (row=0; rowPixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { - /* no zooming */ - for (row=0; rowDriver.WriteCI8Span)(ctx, drawWidth, destX, destY, - src, NULL); - src += rowLength; - destY++; - } - return GL_TRUE; - } - else { - /* with zooming */ - return GL_FALSE; - } - } + ctx->OcclusionResult = GL_TRUE; + ctx->Driver.DrawPixels(ctx, x, y, width, height, format, type, + &ctx->Unpack, pixels); + } + else if (ctx->RenderMode==GL_FEEDBACK) { + /* Feedback the current raster pos info */ + if (ctx->Current.RasterPosValid) { + FLUSH_CURRENT( ctx, 0 ); + FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_DRAW_PIXEL_TOKEN ); + _mesa_feedback_vertex( ctx, + ctx->Current.RasterPos, + ctx->Current.RasterColor, + ctx->Current.RasterIndex, + ctx->Current.RasterTexCoords[0] ); } - else { - /* can't handle this pixel format and/or data type here */ - return GL_FALSE; + } + else if (ctx->RenderMode==GL_SELECT) { + if (ctx->Current.RasterPosValid) { + _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] ); } } - - /* can't do a simple draw, have to use slow path */ - return GL_FALSE; } +void GLAPIENTRY +_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); + if (width < 0 || height < 0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glCopyPixels(width or height < 0)" ); + return; + } -/* - * 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) { - GLdepth zval = (GLdepth) (ctx->Current.RasterPos[2] * DEPTH_SCALE); - GLint i; - for (i = 0; i < drawWidth; i++) { - zspan[i] = zval; - } + if (ctx->NewState) { + _mesa_update_state(ctx); } - /* - * General solution - */ - for (row = 0; row < height; row++, y++) { - GLuint indexes[MAX_WIDTH]; - const GLvoid *source = gl_pixel_addr_in_image(&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); - if (zoom) { - gl_write_zoomed_index_span(ctx, drawWidth, x, y, zspan, indexes, desty); + if (ctx->RenderMode==GL_RENDER) { + /* Destination of copy: */ + if (!ctx->Current.RasterPosValid) { + return; } - else { - gl_write_index_span(ctx, drawWidth, x, y, zspan, indexes, GL_BITMAP); + + /* Round, to satisfy conformance tests (matches SGI's OpenGL) */ + destx = IROUND(ctx->Current.RasterPos[0]); + desty = IROUND(ctx->Current.RasterPos[1]); + + ctx->OcclusionResult = GL_TRUE; + + ctx->Driver.CopyPixels( ctx, srcx, srcy, width, height, destx, desty, + type ); + } + else if (ctx->RenderMode == GL_FEEDBACK) { + if (ctx->Current.RasterPosValid) { + FLUSH_CURRENT( ctx, 0 ); + FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_COPY_PIXEL_TOKEN ); + _mesa_feedback_vertex( ctx, + ctx->Current.RasterPos, + ctx->Current.RasterColor, + ctx->Current.RasterIndex, + ctx->Current.RasterTexCoords[0] ); } } + else if (ctx->RenderMode == GL_SELECT) { + _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] ); + } } +#endif -/* - * 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 ) + +void GLAPIENTRY +_mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, 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)"); + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (width < 0 || height < 0) { + _mesa_error( ctx, GL_INVALID_VALUE, + "glReadPixels(width=%d height=%d)", width, height ); return; } - drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; + if (!pixels) { + _mesa_error( ctx, GL_INVALID_VALUE, "glReadPixels(pixels)" ); + return; + } - 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 = gl_pixel_addr_in_image(&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_TRUE); + if (ctx->NewState) + _mesa_update_state(ctx); - if (zoom) { - gl_write_zoomed_stencil_span( ctx, (GLuint) drawWidth, x, y, - values, desty ); - } - else { - gl_write_stencil_span( ctx, (GLuint) drawWidth, x, y, values ); - } - } + ctx->Driver.ReadPixels(ctx, x, y, width, height, + format, type, &ctx->Pack, pixels); } -/* - * 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 ) + + +void GLAPIENTRY +_mesa_Bitmap( GLsizei width, GLsizei height, + GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, + const GLubyte *bitmap ) { - 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; - GLubyte rgba[MAX_WIDTH][4]; - GLuint ispan[MAX_WIDTH]; - GLint drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; - - if (type != GL_UNSIGNED_BYTE - && type != GL_UNSIGNED_BYTE - && type != GL_UNSIGNED_SHORT - && type != GL_UNSIGNED_SHORT - && type != GL_UNSIGNED_INT - && type != GL_UNSIGNED_INT - && type != GL_FLOAT) { - gl_error(ctx, GL_INVALID_ENUM, "glDrawPixels(type)"); + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (width < 0 || height < 0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glBitmap(width or height < 0)" ); return; } - /* Colors or indexes */ - if (ctx->Visual->RGBAflag) { - GLint r = (GLint) (ctx->Current.RasterColor[0] * 255.0F); - GLint g = (GLint) (ctx->Current.RasterColor[1] * 255.0F); - GLint b = (GLint) (ctx->Current.RasterColor[2] * 255.0F); - GLint a = (GLint) (ctx->Current.RasterColor[3] * 255.0F); - 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 (ctx->Current.RasterPosValid == GL_FALSE) { + return; /* do nothing */ } - 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++) { - const GLdepth *zptr = gl_pixel_addr_in_image(&ctx->Unpack, - pixels, width, height, GL_DEPTH_COMPONENT, type, 0, row, 0); - gl_write_rgba_span( ctx, width, x, y, zptr, rgba, GL_BITMAP ); - } - } - else if (type==GL_UNSIGNED_INT && sizeof(GLdepth)==sizeof(GLuint) - && !bias_or_scale && !zoom && ctx->Visual->RGBAflag) { - /* Special case: directly write 32-bit depth values */ - GLint i, row; - /* Compute shift value to scale 32-bit uints down to depth values. */ - GLuint shift = 0; - GLuint max = MAX_DEPTH; - while ((max & 0x80000000) == 0) { - max = max << 1; - shift++; - } - for (row = 0; row < height; row++, y++) { - GLdepth zspan[MAX_WIDTH]; - const GLdepth *zptr = gl_pixel_addr_in_image(&ctx->Unpack, - pixels, width, height, GL_DEPTH_COMPONENT, type, 0, row, 0); - for (i=0;i> shift; - } - gl_write_rgba_span( ctx, width, x, y, zspan, rgba, GL_BITMAP ); - } - } - else { - /* General case */ - GLint row; - for (row = 0; row < height; row++, y++) { - GLdepth zspan[MAX_WIDTH]; - const GLvoid *src = gl_pixel_addr_in_image(&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 ); - if (ctx->Visual->RGBAflag) { - if (zoom) { - gl_write_zoomed_rgba_span(ctx, width, x, y, zspan, - (const GLubyte (*)[4])rgba, desty); - } - else { - gl_write_rgba_span(ctx, width, x, y, zspan, rgba, GL_BITMAP); - } - } - else { - if (zoom) { - gl_write_zoomed_index_span(ctx, width, x, y, zspan, - ispan, GL_BITMAP); - } - else { - gl_write_index_span(ctx, width, x, y, zspan, ispan, GL_BITMAP); - } + if (ctx->RenderMode==GL_RENDER) { + if (bitmap) { + /* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */ + GLint x = IFLOOR(ctx->Current.RasterPos[0] - xorig); + GLint y = IFLOOR(ctx->Current.RasterPos[1] - yorig); + + if (ctx->NewState) { + _mesa_update_state(ctx); } + ctx->OcclusionResult = GL_TRUE; + ctx->Driver.Bitmap( ctx, x, y, width, height, &ctx->Unpack, 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; - - /* Try an optimized glDrawPixels first */ - if (simple_DrawPixels(ctx, x, y, width, height, format, type, pixels)) - return; - - /* Fragment depth values */ - if (ctx->Depth.Test) { - /* fill in array of z values */ - GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * DEPTH_SCALE); - GLint i; - for (i=0;iRenderMode==GL_FEEDBACK) { + if (ctx->Current.RasterPosValid) { + FLUSH_CURRENT(ctx, 0); + FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_BITMAP_TOKEN ); + _mesa_feedback_vertex( ctx, + ctx->Current.RasterPos, + ctx->Current.RasterColor, + ctx->Current.RasterIndex, + ctx->Current.RasterTexCoords[0] ); } } - - - if (ctx->RasterMask == 0 && !zoom - && x >= 0 && y >= 0 - && x + width <= ctx->Buffer->Width - && y + height <= ctx->Buffer->Height) { - quickDraw = GL_TRUE; - } else { - quickDraw = GL_FALSE; + ASSERT(ctx->RenderMode == GL_SELECT); + /* Bitmaps don't generate selection hits. See appendix B of 1.1 spec. */ } +#endif - /* - * General solution - */ - { - GLubyte rgba[MAX_WIDTH][4]; - GLint row; - if (width > MAX_WIDTH) - width = MAX_WIDTH; - for (row = 0; row < height; row++, y++) { - const GLvoid *source = gl_pixel_addr_in_image(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); - - if (quickDraw) { - (*ctx->Driver.WriteRGBASpan)( ctx, width, x, y, - (CONST GLubyte (*)[]) rgba, NULL); - } - else if (zoom) { - gl_write_zoomed_rgba_span( ctx, width, x, y, zspan, - (CONST GLubyte (*)[]) rgba, desty ); - } - else { - gl_write_rgba_span( ctx, (GLuint) width, x, y, zspan, rgba, GL_BITMAP); - } - } - } + /* update raster position */ + ctx->Current.RasterPos[0] += xmove; + ctx->Current.RasterPos[1] += ymove; } +#if 0 /* experimental */ /* - * Execute glDrawPixels + * Execute glDrawDepthPixelsMESA(). This function accepts both a color + * image and depth (Z) image. Rasterization produces fragments with + * color and Z taken from these images. This function is intended for + * Z-compositing. Normally, this operation requires two glDrawPixels + * calls with stencil testing. */ -void -_mesa_DrawPixels( GLsizei width, GLsizei height, - GLenum format, GLenum type, const GLvoid *pixels ) +void GLAPIENTRY +_mesa_DrawDepthPixelsMESA( GLsizei width, GLsizei height, + GLenum colorFormat, GLenum colorType, + const GLvoid *colors, + GLenum depthType, const GLvoid *depths ) { GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDrawPixels"); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (width < 0 || height < 0) { + _mesa_error( ctx, GL_INVALID_VALUE, + "glDrawDepthPixelsMESA(width or height < 0" ); + return; + } if (ctx->RenderMode==GL_RENDER) { GLint x, y; - if (!pixels || !ctx->Current.RasterPosValid) { + if (!colors || !depths || !ctx->Current.RasterPosValid) { return; } - x = (GLint) (ctx->Current.RasterPos[0] + 0.5F); - y = (GLint) (ctx->Current.RasterPos[1] + 0.5F); - - 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_index_pixels(ctx, x, y, width, height, type, pixels); - else - draw_rgba_pixels(ctx, x,y, width, height, format, 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)" ); - return; + if (ctx->NewState) { + _mesa_update_state(ctx); } + + /* Round, to satisfy conformance tests (matches SGI's OpenGL) */ + x = IROUND(ctx->Current.RasterPos[0]); + y = IROUND(ctx->Current.RasterPos[1]); + + ctx->OcclusionResult = GL_TRUE; + ctx->Driver.DrawDepthPixelsMESA(ctx, x, y, width, height, + colorFormat, colorType, colors, + depthType, depths, &ctx->Unpack); } else if (ctx->RenderMode==GL_FEEDBACK) { + /* Feedback the current raster pos info */ if (ctx->Current.RasterPosValid) { - GLfloat color[4]; - GLfloat texcoord[4], invq; - UBYTE_RGBA_TO_FLOAT_RGBA(color, ctx->Current.ByteColor); - invq = 1.0F / ctx->Current.Texcoord[0][3]; - texcoord[0] = ctx->Current.Texcoord[0][0] * invq; - texcoord[1] = ctx->Current.Texcoord[0][1] * invq; - texcoord[2] = ctx->Current.Texcoord[0][2] * invq; - texcoord[3] = ctx->Current.Texcoord[0][3]; + FLUSH_CURRENT( ctx, 0 ); FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_DRAW_PIXEL_TOKEN ); - gl_feedback_vertex( ctx, - ctx->Current.RasterPos, - color, ctx->Current.Index, texcoord ); + _mesa_feedback_vertex( ctx, + ctx->Current.RasterPos, + ctx->Current.RasterColor, + ctx->Current.RasterIndex, + ctx->Current.RasterTexCoords[0] ); } } else if (ctx->RenderMode==GL_SELECT) { if (ctx->Current.RasterPosValid) { - gl_update_hitflag( ctx, ctx->Current.RasterPos[2] ); + _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] ); } } } +#endif