⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xm_span.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Mesa 3-D graphics library * Version:  6.3 * * Copyright (C) 1999-2004  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 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */#include "glxheader.h"#include "colormac.h"#include "context.h"#include "depth.h"#include "drawpix.h"#include "extensions.h"#include "macros.h"#include "imports.h"#include "mtypes.h"#include "state.h"#include "xmesaP.h"#include "swrast/swrast.h"/* * The following functions are used to trap XGetImage() calls which * generate BadMatch errors if the drawable isn't mapped. */#ifndef XFree86Serverstatic int caught_xgetimage_error = 0;static int (*old_xerror_handler)( XMesaDisplay *dpy, XErrorEvent *ev );static unsigned long xgetimage_serial;/* * This is the error handler which will be called if XGetImage fails. */static int xgetimage_error_handler( XMesaDisplay *dpy, XErrorEvent *ev ){   if (ev->serial==xgetimage_serial && ev->error_code==BadMatch) {      /* caught the expected error */      caught_xgetimage_error = 0;   }   else {      /* call the original X error handler, if any.  otherwise ignore */      if (old_xerror_handler) {         (*old_xerror_handler)( dpy, ev );      }   }   return 0;}/* * Call this right before XGetImage to setup error trap. */static void catch_xgetimage_errors( XMesaDisplay *dpy ){   xgetimage_serial = NextRequest( dpy );   old_xerror_handler = XSetErrorHandler( xgetimage_error_handler );   caught_xgetimage_error = 0;}/* * Call this right after XGetImage to check if an error occured. */static int check_xgetimage_errors( void ){   /* restore old handler */   (void) XSetErrorHandler( old_xerror_handler );   /* return 0=no error, 1=error caught */   return caught_xgetimage_error;}#endif/* * Read a pixel from an X drawable. */static unsigned long read_pixel( XMesaDisplay *dpy,                                 XMesaDrawable d, int x, int y ){   unsigned long p;#ifndef XFree86Server   XMesaImage *pixel = NULL;   int error;   catch_xgetimage_errors( dpy );   pixel = XGetImage( dpy, d, x, y, 1, 1, AllPlanes, ZPixmap );   error = check_xgetimage_errors();   if (pixel && !error) {      p = XMesaGetPixel( pixel, 0, 0 );   }   else {      p = 0;   }   if (pixel) {      XMesaDestroyImage( pixel );   }#else   (*dpy->GetImage)(d, x, y, 1, 1, ZPixmap, ~0L, (pointer)&p);#endif   return p;}/* * The Mesa library needs to be able to draw pixels in a number of ways: *   1. RGB vs Color Index *   2. as horizontal spans (polygons, images) vs random locations (points, *      lines) *   3. different color per-pixel or same color for all pixels * * Furthermore, the X driver needs to support rendering to 3 possible * "buffers", usually one, but sometimes two at a time: *   1. The front buffer as an X window *   2. The back buffer as a Pixmap *   3. The back buffer as an XImage * * Finally, if the back buffer is an XImage, we can avoid using XPutPixel and * optimize common cases such as 24-bit and 8-bit modes. * * By multiplication, there's at least 48 possible combinations of the above. * * Below are implementations of the most commonly used combinations.  They are * accessed through function pointers which get initialized here and are used * directly from the Mesa library.  The 8 function pointers directly correspond * to the first 3 cases listed above. * * * The function naming convention is: * *   [put|get]_[mono]_[row|values]_[format]_[pixmap|ximage] * * New functions optimized for specific cases can be added without too much * trouble.  An example might be the 24-bit TrueColor mode 8A8R8G8B which is * found on IBM RS/6000 X servers. *//**********************************************************************//*** Write COLOR SPAN functions                                     ***//**********************************************************************/#define PUT_ROW_ARGS \	GLcontext *ctx,					\	struct gl_renderbuffer *rb,			\	GLuint n, GLint x, GLint y,			\	const void *values, const GLubyte mask[]#define RGB_SPAN_ARGS \	GLcontext *ctx,					\	struct gl_renderbuffer *rb,			\	GLuint n, GLint x, GLint y,			\	const void *values, const GLubyte mask[]#define GET_XRB(XRB) \   struct xmesa_renderbuffer *XRB = xmesa_renderbuffer(rb)/* * Write a span of PF_TRUECOLOR pixels to a pixmap. */static void put_row_TRUECOLOR_pixmap( PUT_ROW_ARGS ){   const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;   const XMesaContext xmesa = XMESA_CONTEXT(ctx);   GET_XRB(xrb);   XMesaDisplay *dpy = XMESA_BUFFER(ctx->DrawBuffer)->display;   XMesaDrawable buffer = xrb->drawable;   XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;   register GLuint i;   y = YFLIP(xrb, y);   if (mask) {      for (i=0;i<n;i++,x++) {         if (mask[i]) {            unsigned long p;            PACK_TRUECOLOR( p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );            XMesaSetForeground( dpy, gc, p );            XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );         }      }   }   else {      /* draw all pixels */      XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;      for (i=0;i<n;i++) {         unsigned long p;         PACK_TRUECOLOR( p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );         XMesaPutPixel( rowimg, i, 0, p );      }      XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );   }}/* * Write a span of PF_TRUECOLOR pixels to a pixmap. */static void put_row_rgb_TRUECOLOR_pixmap( RGB_SPAN_ARGS ){   const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;   const XMesaContext xmesa = XMESA_CONTEXT(ctx);   GET_XRB(xrb);   XMesaDisplay *dpy = xmesa->xm_visual->display;   XMesaDrawable buffer = xrb->drawable;   XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;   register GLuint i;   y = YFLIP(xrb, y);   if (mask) {      for (i=0;i<n;i++,x++) {         if (mask[i]) {            unsigned long p;            PACK_TRUECOLOR( p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );            XMesaSetForeground( dpy, gc, p );            XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );         }      }   }   else {      /* draw all pixels */      XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;      for (i=0;i<n;i++) {         unsigned long p;         PACK_TRUECOLOR( p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );         XMesaPutPixel( rowimg, i, 0, p );      }      XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );   }}/* * Write a span of PF_TRUEDITHER pixels to a pixmap. */static void put_row_TRUEDITHER_pixmap( PUT_ROW_ARGS ){   const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;   const XMesaContext xmesa = XMESA_CONTEXT(ctx);   GET_XRB(xrb);   XMesaDisplay *dpy = xmesa->xm_visual->display;   XMesaDrawable buffer = xrb->drawable;   XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;   register GLuint i;   y = YFLIP(xrb, y);   if (mask) {      for (i=0;i<n;i++,x++) {         if (mask[i]) {            unsigned long p;            PACK_TRUEDITHER(p, x, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);            XMesaSetForeground( dpy, gc, p );            XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );         }      }   }   else {      XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;      for (i=0;i<n;i++) {         unsigned long p;         PACK_TRUEDITHER(p, x+i, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);         XMesaPutPixel( rowimg, i, 0, p );      }      XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );   }}/* * Write a span of PF_TRUEDITHER pixels to a pixmap (no alpha). */static void put_row_rgb_TRUEDITHER_pixmap( RGB_SPAN_ARGS ){   const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;   const XMesaContext xmesa = XMESA_CONTEXT(ctx);   GET_XRB(xrb);   XMesaDisplay *dpy = xmesa->xm_visual->display;   XMesaDrawable buffer = xrb->drawable;   XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;   register GLuint i;   y = YFLIP(xrb, y);   if (mask) {      for (i=0;i<n;i++,x++) {         if (mask[i]) {            unsigned long p;            PACK_TRUEDITHER(p, x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);            XMesaSetForeground( dpy, gc, p );            XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );         }      }   }   else {      XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;      for (i=0;i<n;i++) {         unsigned long p;         PACK_TRUEDITHER(p, x+i, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);         XMesaPutPixel( rowimg, i, 0, p );      }      XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );   }}/* * Write a span of PF_8A8B8G8R pixels to a pixmap. */static void put_row_8A8B8G8R_pixmap( PUT_ROW_ARGS ){   const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;   const XMesaContext xmesa = XMESA_CONTEXT(ctx);   GET_XRB(xrb);   XMesaDisplay *dpy = xmesa->xm_visual->display;   XMesaDrawable buffer = xrb->drawable;   XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;   register GLuint i;   y = YFLIP(xrb, y);   if (mask) {      for (i=0;i<n;i++,x++) {         if (mask[i]) {            XMesaSetForeground( dpy, gc,                         PACK_8A8B8G8R(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP]) );            XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );         }      }   }   else {      /* draw all pixels */      XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;      register GLuint *ptr4 = (GLuint *) rowimg->data;      for (i=0;i<n;i++) {         *ptr4++ = PACK_8A8B8G8R( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );      }      XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );   }}/* * Write a span of PF_8A8B8G8R pixels to a pixmap (no alpha). */static void put_row_rgb_8A8B8G8R_pixmap( RGB_SPAN_ARGS ){   const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;   const XMesaContext xmesa = XMESA_CONTEXT(ctx);   GET_XRB(xrb);   XMesaDisplay *dpy = xmesa->xm_visual->display;   XMesaDrawable buffer = xrb->drawable;   XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;   register GLuint i;   y = YFLIP(xrb, y);   if (mask) {      for (i=0;i<n;i++,x++) {         if (mask[i]) {            XMesaSetForeground( dpy, gc,                   PACK_8B8G8R(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]) );            XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );         }      }   }   else {      /* draw all pixels */      XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;      register GLuint *ptr4 = (GLuint *) rowimg->data;      for (i=0;i<n;i++) {         *ptr4++ = PACK_8B8G8R(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);      }      XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );   }}/* * Write a span of PF_8A8R8G8B pixels to a pixmap. */static void put_row_8A8R8G8B_pixmap( PUT_ROW_ARGS ){   const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;   const XMesaContext xmesa = XMESA_CONTEXT(ctx);   GET_XRB(xrb);   XMesaDisplay *dpy = xmesa->xm_visual->display;   XMesaDrawable buffer = xrb->drawable;   XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;   register GLuint i;   y = YFLIP(xrb, y);   if (mask) {      for (i=0;i<n;i++,x++) {         if (mask[i]) {            XMesaSetForeground( dpy, gc,                         PACK_8A8R8G8B(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP]) );            XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );         }      }   }   else {      /* draw all pixels */      XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;      register GLuint *ptr4 = (GLuint *) rowimg->data;      for (i=0;i<n;i++) {         *ptr4++ = PACK_8A8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );      }      XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );   }}/* * Write a span of PF_8A8R8G8B pixels to a pixmap (no alpha). */static void put_row_rgb_8A8R8G8B_pixmap( RGB_SPAN_ARGS ){   const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;   const XMesaContext xmesa = XMESA_CONTEXT(ctx);   GET_XRB(xrb);   XMesaDisplay *dpy = xmesa->xm_visual->display;   XMesaDrawable buffer = xrb->drawable;   XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;   register GLuint i;   y = YFLIP(xrb, y);   if (mask) {      for (i=0;i<n;i++,x++) {         if (mask[i]) {            XMesaSetForeground( dpy, gc,                   PACK_8R8G8B(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]) );            XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );         }      }   }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -