📄 xm_api.c
字号:
/* * Mesa 3-D graphics library * Version: 7.1 * * Copyright (C) 1999-2007 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. *//** * \file xm_api.c * * All the XMesa* API functions. * * * NOTES: * * The window coordinate system origin (0,0) is in the lower-left corner * of the window. X11's window coordinate origin is in the upper-left * corner of the window. Therefore, most drawing functions in this * file have to flip Y coordinates. * * Define USE_XSHM in the Makefile with -DUSE_XSHM if you want to compile * in support for the MIT Shared Memory extension. If enabled, when you * use an Ximage for the back buffer in double buffered mode, the "swap" * operation will be faster. You must also link with -lXext. * * Byte swapping: If the Mesa host and the X display use a different * byte order then there's some trickiness to be aware of when using * XImages. The byte ordering used for the XImage is that of the X * display, not the Mesa host. * The color-to-pixel encoding for True/DirectColor must be done * according to the display's visual red_mask, green_mask, and blue_mask. * If XPutPixel is used to put a pixel into an XImage then XPutPixel will * do byte swapping if needed. If one wants to directly "poke" the pixel * into the XImage's buffer then the pixel must be byte swapped first. In * Mesa, when byte swapping is needed we use the PF_TRUECOLOR pixel format * and use XPutPixel everywhere except in the implementation of * glClear(GL_COLOR_BUFFER_BIT). We want this function to be fast so * instead of using XPutPixel we "poke" our values after byte-swapping * the clear pixel value if needed. * */#ifdef __CYGWIN__#undef WIN32#undef __WIN32__#endif#include "glxheader.h"#include "GL/xmesa.h"#include "xmesaP.h"#include "main/context.h"#include "main/extensions.h"#include "main/framebuffer.h"#include "glapi/glthread.h"#include "main/imports.h"#include "main/macros.h"#include "main/renderbuffer.h"#include "main/teximage.h"#include "swrast/swrast.h"#include "swrast_setup/swrast_setup.h"#include "vbo/vbo.h"#include "tnl/tnl.h"#include "tnl/t_context.h"#include "tnl/t_pipeline.h"#include "drivers/common/driverfuncs.h"/** * Global X driver lock */_glthread_Mutex _xmesa_lock;/** * Lookup tables for HPCR pixel format: */static short hpcr_rgbTbl[3][256] = {{ 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239},{ 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239},{ 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47, 48, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63, 64, 64, 65, 65, 66, 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 72, 72, 73, 73, 74, 74, 75, 75, 76, 76, 77, 77, 78, 78, 79, 79, 80, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, 86, 86, 87, 87, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223}};/**********************************************************************//***** X Utility Functions *****//**********************************************************************//** * Return the host's byte order as LSBFirst or MSBFirst ala X. */#ifndef XFree86Serverstatic int host_byte_order( void ){ int i = 1; char *cptr = (char *) &i; return (*cptr==1) ? LSBFirst : MSBFirst;}#endif/** * Check if the X Shared Memory extension is available. * Return: 0 = not available * 1 = shared XImage support available * 2 = shared Pixmap support available also */static int check_for_xshm( XMesaDisplay *display ){#if defined(USE_XSHM) && !defined(XFree86Server) int major, minor, ignore; Bool pixmaps; if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) { if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) { return (pixmaps==True) ? 2 : 1; } else { return 0; } } else { return 0; }#else /* No XSHM support */ return 0;#endif}/** * Apply gamma correction to an intensity value in [0..max]. Return the * new intensity value. */static GLintgamma_adjust( GLfloat gamma, GLint value, GLint max ){ if (gamma == 1.0) { return value; } else { double x = (double) value / (double) max; return IROUND_POS((GLfloat) max * _mesa_pow(x, 1.0F/gamma)); }}/** * Return the true number of bits per pixel for XImages. * For example, if we request a 24-bit deep visual we may actually need/get * 32bpp XImages. This function returns the appropriate bpp. * Input: dpy - the X display * visinfo - desribes the visual to be used for XImages * Return: true number of bits per pixel for XImages */static intbits_per_pixel( XMesaVisual xmv ){#ifdef XFree86Server const int depth = xmv->nplanes; int i; assert(depth > 0); for (i = 0; i < screenInfo.numPixmapFormats; i++) { if (screenInfo.formats[i].depth == depth) return screenInfo.formats[i].bitsPerPixel; } return depth; /* should never get here, but this should be safe */#else XMesaDisplay *dpy = xmv->display; XMesaVisualInfo visinfo = xmv->visinfo; XMesaImage *img; int bitsPerPixel; /* Create a temporary XImage */ img = XCreateImage( dpy, visinfo->visual, visinfo->depth, ZPixmap, 0, /*format, offset*/ (char*) MALLOC(8), /*data*/ 1, 1, /*width, height*/ 32, /*bitmap_pad*/ 0 /*bytes_per_line*/ ); assert(img); /* grab the bits/pixel value */ bitsPerPixel = img->bits_per_pixel; /* free the XImage */ _mesa_free( img->data ); img->data = NULL; XMesaDestroyImage( img ); return bitsPerPixel;#endif}/* * Determine if a given X window ID is valid (window exists). * Do this by calling XGetWindowAttributes() for the window and * checking if we catch an X error. * Input: dpy - the display * win - the window to check for existance * Return: GL_TRUE - window exists * GL_FALSE - window doesn't exist */#ifndef XFree86Serverstatic GLboolean WindowExistsFlag;static int window_exists_err_handler( XMesaDisplay* dpy, XErrorEvent* xerr ){ (void) dpy; if (xerr->error_code == BadWindow) { WindowExistsFlag = GL_FALSE; } return 0;}static GLboolean window_exists( XMesaDisplay *dpy, Window win ){ XWindowAttributes wa; int (*old_handler)( XMesaDisplay*, XErrorEvent* ); WindowExistsFlag = GL_TRUE; old_handler = XSetErrorHandler(window_exists_err_handler); XGetWindowAttributes( dpy, win, &wa ); /* dummy request */ XSetErrorHandler(old_handler); return WindowExistsFlag;}static Statusget_drawable_size( XMesaDisplay *dpy, Drawable d, GLuint *width, GLuint *height ){ Window root; Status stat; int xpos, ypos; unsigned int w, h, bw, depth; stat = XGetGeometry(dpy, d, &root, &xpos, &ypos, &w, &h, &bw, &depth); *width = w; *height = h; return stat;}#endif/** * Return the size of the window (or pixmap) that corresponds to the * given XMesaBuffer. * \param width returns width in pixels * \param height returns height in pixels */voidxmesa_get_window_size(XMesaDisplay *dpy, XMesaBuffer b, GLuint *width, GLuint *height){#ifdef XFree86Server *width = MIN2(b->frontxrb->drawable->width, MAX_WIDTH); *height = MIN2(b->frontxrb->drawable->height, MAX_HEIGHT);#else Status stat; _glthread_LOCK_MUTEX(_xmesa_lock); XSync(b->xm_visual->display, 0); /* added for Chromium */ stat = get_drawable_size(dpy, b->frontxrb->pixmap, width, height); _glthread_UNLOCK_MUTEX(_xmesa_lock); if (!stat) { /* probably querying a window that's recently been destroyed */ _mesa_warning(NULL, "XGetGeometry failed!\n"); *width = *height = 1; }#endif}/**********************************************************************//***** Linked list of XMesaBuffers *****//**********************************************************************/XMesaBuffer XMesaBufferList = NULL;/** * Allocate a new XMesaBuffer object which corresponds to the given drawable. * Note that XMesaBuffer is derived from GLframebuffer. * The new XMesaBuffer will not have any size (Width=Height=0). * * \param d the corresponding X drawable (window or pixmap) * \param type either WINDOW, PIXMAP or PBUFFER, describing d * \param vis the buffer's visual * \param cmap the window's colormap, if known. * \return new XMesaBuffer or NULL if any problem */static XMesaBuffercreate_xmesa_buffer(XMesaDrawable d, BufferType type, XMesaVisual vis, XMesaColormap cmap){ XMesaBuffer b; ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER); b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer); if (!b) return NULL; b->display = vis->display; b->xm_visual = vis; b->type = type; b->cmap = cmap; _mesa_initialize_framebuffer(&b->mesa_buffer, &vis->mesa_visual); b->mesa_buffer.Delete = xmesa_delete_framebuffer; /* * Front renderbuffer */ b->frontxrb = xmesa_new_renderbuffer(NULL, 0, &vis->mesa_visual, GL_FALSE); if (!b->frontxrb) { _mesa_free(b); return NULL; } b->frontxrb->Parent = b; b->frontxrb->drawable = d; b->frontxrb->pixmap = (XMesaPixmap) d; _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_FRONT_LEFT, &b->frontxrb->Base); /* * Back renderbuffer */ if (vis->mesa_visual.doubleBufferMode) { b->backxrb = xmesa_new_renderbuffer(NULL, 0, &vis->mesa_visual, GL_TRUE); if (!b->backxrb) { /* XXX free front xrb too */ _mesa_free(b); return NULL; } b->backxrb->Parent = b; /* determine back buffer implementation */ b->db_mode = vis->ximage_flag ? BACK_XIMAGE : BACK_PIXMAP; _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_BACK_LEFT, &b->backxrb->Base); } /* * Software alpha planes */ if (vis->mesa_visual.alphaBits > 0 && vis->undithered_pf != PF_8A8B8G8R && vis->undithered_pf != PF_8A8R8G8B) { /* Visual has alpha, but pixel format doesn't support it.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -