xm_api.c revision 71e3abc014cf8a1c18dcfd87517546a47ba41b6d
10f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Mesa 3-D graphics library 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Version: 7.1 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 50f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Permission is hereby granted, free of charge, to any person obtaining a 8a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) * copy of this software and associated documentation files (the "Software"), 9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) * to deal in the Software without restriction, including without limitation 10ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * the rights to use, copy, modify, merge, publish, distribute, sublicense, 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and/or sell copies of the Software, and to permit persons to whom the 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Software is furnished to do so, subject to the following conditions: 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * The above copyright notice and this permission notice shall be included 153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * in all copies or substantial portions of the Software. 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * \file xm_api.c 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * All the XMesa* API functions. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * NOTES: 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * The window coordinate system origin (0,0) is in the lower-left corner 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * of the window. X11's window coordinate origin is in the upper-left 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * corner of the window. Therefore, most drawing functions in this 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * file have to flip Y coordinates. 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * Define USE_XSHM in the Makefile with -DUSE_XSHM if you want to compile 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * in support for the MIT Shared Memory extension. If enabled, when you 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * use an Ximage for the back buffer in double buffered mode, the "swap" 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * operation will be faster. You must also link with -lXext. 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Byte swapping: If the Mesa host and the X display use a different 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * byte order then there's some trickiness to be aware of when using 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * XImages. The byte ordering used for the XImage is that of the X 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * display, not the Mesa host. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The color-to-pixel encoding for True/DirectColor must be done 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * according to the display's visual red_mask, green_mask, and blue_mask. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If XPutPixel is used to put a pixel into an XImage then XPutPixel will 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * do byte swapping if needed. If one wants to directly "poke" the pixel 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * into the XImage's buffer then the pixel must be byte swapped first. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __CYGWIN__ 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef WIN32 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef __WIN32__ 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "xm_api.h" 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "main/context.h" 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "main/framebuffer.h" 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "state_tracker/st_public.h" 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "state_tracker/st_context.h" 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "pipe/p_defines.h" 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "pipe/p_screen.h" 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "pipe/p_context.h" 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "trace/tr_screen.h" 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "trace/tr_context.h" 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "trace/tr_texture.h" 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "xm_winsys.h" 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <GL/glx.h> 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/* Driver interface routines, set up by xlib backend on library 7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) * _init(). These are global in the same way that function names are 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * global. 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct xm_driver driver; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void xmesa_set_driver( const struct xm_driver *templ ) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) driver = *templ; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Global X driver lock 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochpipe_mutex _xmesa_lock; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct pipe_screen *_screen = NULL; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct pipe_screen *screen = NULL; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/**********************************************************************/ 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/***** X Utility Functions *****/ 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**********************************************************************/ 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Return the host's byte order as LSBFirst or MSBFirst ala X. 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int host_byte_order( void ) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int i = 1; 1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) char *cptr = (char *) &i; 1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return (*cptr==1) ? LSBFirst : MSBFirst; 1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)/** 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * Check if the X Shared Memory extension is available. 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * Return: 0 = not available 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * 1 = shared XImage support available 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * 2 = shared Pixmap support available also 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) */ 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int xmesa_check_for_xshm( Display *display ) 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles){ 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(USE_XSHM) 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int major, minor, ignore; 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Bool pixmaps; 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (getenv("SP_NO_RAST")) 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 0; 12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (getenv("MESA_NOSHM")) { 13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 0; 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) { 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) { 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return (pixmaps==True) ? 2 : 1; 13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) else { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* No XSHM support */ 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch/** 1527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * Return the true number of bits per pixel for XImages. 1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * For example, if we request a 24-bit deep visual we may actually need/get 1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * 32bpp XImages. This function returns the appropriate bpp. 1557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * Input: dpy - the X display 1567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * visinfo - desribes the visual to be used for XImages 1577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * Return: true number of bits per pixel for XImages 1588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 1598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)static int 1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbits_per_pixel( XMesaVisual xmv ) 1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch{ 1627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Display *dpy = xmv->display; 1637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch XVisualInfo * visinfo = xmv->visinfo; 1647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch XImage *img; 1658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int bitsPerPixel; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Create a temporary XImage */ 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) img = XCreateImage( dpy, visinfo->visual, visinfo->depth, 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ZPixmap, 0, /*format, offset*/ 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (char*) MALLOC(8), /*data*/ 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, 1, /*width, height*/ 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32, /*bitmap_pad*/ 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0 /*bytes_per_line*/ 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(img); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* grab the bits/pixel value */ 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitsPerPixel = img->bits_per_pixel; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* free the XImage */ 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free( img->data ); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) img->data = NULL; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XDestroyImage( img ); 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return bitsPerPixel; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch/* 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Determine if a given X window ID is valid (window exists). 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Do this by calling XGetWindowAttributes() for the window and 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * checking if we catch an X error. 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Input: dpy - the display 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * win - the window to check for existance 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Return: GL_TRUE - window exists 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * GL_FALSE - window doesn't exist 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic GLboolean WindowExistsFlag; 196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic int window_exists_err_handler( Display* dpy, XErrorEvent* xerr ) 198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch{ 199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (void) dpy; 200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (xerr->error_code == BadWindow) { 201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch WindowExistsFlag = GL_FALSE; 202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic GLboolean window_exists( Display *dpy, Window win ) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XWindowAttributes wa; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int (*old_handler)( Display*, XErrorEvent* ); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WindowExistsFlag = GL_TRUE; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_handler = XSetErrorHandler(window_exists_err_handler); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XGetWindowAttributes( dpy, win, &wa ); /* dummy request */ 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSetErrorHandler(old_handler); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WindowExistsFlag; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Status 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)get_drawable_size( Display *dpy, Drawable d, uint *width, uint *height ) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Window root; 221010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Status stat; 2228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int xpos, ypos; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int w, h, bw, depth; 224010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) stat = XGetGeometry(dpy, d, &root, &xpos, &ypos, &w, &h, &bw, &depth); 225010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) *width = w; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *height = h; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return stat; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Return the size of the window (or pixmap) that corresponds to the 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * given XMesaBuffer. 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \param width returns width in pixels 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \param height returns height in pixels 2368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmesa_get_window_size(Display *dpy, XMesaBuffer b, 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLuint *width, GLuint *height) 240010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles){ 241010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Status stat; 242010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 243010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pipe_mutex_lock(_xmesa_lock); 244010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) XSync(b->xm_visual->display, 0); /* added for Chromium */ 245010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) stat = get_drawable_size(dpy, b->drawable, width, height); 246010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pipe_mutex_unlock(_xmesa_lock); 247010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 248010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!stat) { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* probably querying a window that's recently been destroyed */ 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _mesa_warning(NULL, "XGetGeometry failed!\n"); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *width = *height = 1; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#define GET_REDMASK(__v) __v->mesa_visual.redMask 256010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#define GET_GREENMASK(__v) __v->mesa_visual.greenMask 2578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#define GET_BLUEMASK(__v) __v->mesa_visual.blueMask 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 259010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 260010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)/** 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Choose the pixel format for the given visual. 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This will tell the gallium driver how to pack pixel data into 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * drawing surfaces. 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static GLuint 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)choose_pixel_format(XMesaVisual v) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) boolean native_byte_order = (host_byte_order() == 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImageByteOrder(v->display)); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if ( GET_REDMASK(v) == 0x0000ff 272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) && GET_GREENMASK(v) == 0x00ff00 273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) && GET_BLUEMASK(v) == 0xff0000 274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) && v->BitsPerPixel == 32) { 275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (native_byte_order) { 276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /* no byteswapping needed */ 277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return 0 /* PIXEL_FORMAT_U_A8_B8_G8_R8 */; 278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) else { 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PIPE_FORMAT_R8G8B8A8_UNORM; 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if ( GET_REDMASK(v) == 0xff0000 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) && GET_GREENMASK(v) == 0x00ff00 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) && GET_BLUEMASK(v) == 0x0000ff 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) && v->BitsPerPixel == 32) { 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (native_byte_order) { 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* no byteswapping needed */ 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PIPE_FORMAT_A8R8G8B8_UNORM; 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) else { 292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return PIPE_FORMAT_B8G8R8A8_UNORM; 293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) else if ( GET_REDMASK(v) == 0x0000ff00 296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) && GET_GREENMASK(v) == 0x00ff0000 297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) && GET_BLUEMASK(v) == 0xff000000 298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) && v->BitsPerPixel == 32) { 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (native_byte_order) { 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* no byteswapping needed */ 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PIPE_FORMAT_B8G8R8A8_UNORM; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PIPE_FORMAT_A8R8G8B8_UNORM; 3057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if ( GET_REDMASK(v) == 0xf800 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && GET_GREENMASK(v) == 0x07e0 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && GET_BLUEMASK(v) == 0x001f 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) && native_byte_order 3117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch && v->BitsPerPixel == 16) { 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 5-6-5 RGB */ 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PIPE_FORMAT_R5G6B5_UNORM; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(0); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**********************************************************************/ 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/***** Linked list of XMesaBuffers *****/ 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**********************************************************************/ 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)XMesaBuffer XMesaBufferList = NULL; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Allocate a new XMesaBuffer object which corresponds to the given drawable. 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Note that XMesaBuffer is derived from GLframebuffer. 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The new XMesaBuffer will not have any size (Width=Height=0). 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \param d the corresponding X drawable (window or pixmap) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \param type either WINDOW, PIXMAP or PBUFFER, describing d 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \param vis the buffer's visual 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \param cmap the window's colormap, if known. 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \return new XMesaBuffer or NULL if any problem 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static XMesaBuffer 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)create_xmesa_buffer(Drawable d, BufferType type, 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XMesaVisual vis, Colormap cmap) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) XMesaBuffer b; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLframebuffer *fb; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum pipe_format colorFormat, depthFormat, stencilFormat; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint width, height; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!b) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b->drawable = d; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b->xm_visual = vis; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b->type = type; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b->cmap = cmap; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* determine PIPE_FORMATs for buffers */ 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) colorFormat = choose_pixel_format(vis); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (vis->mesa_visual.depthBits == 0) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) depthFormat = PIPE_FORMAT_NONE; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef GALLIUM_CELL /* XXX temporary for Cell! */ 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) depthFormat = PIPE_FORMAT_S8Z24_UNORM; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 3708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) else if (vis->mesa_visual.depthBits <= 16) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) depthFormat = PIPE_FORMAT_Z16_UNORM; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (vis->mesa_visual.depthBits <= 24) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) depthFormat = PIPE_FORMAT_S8Z24_UNORM; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) depthFormat = PIPE_FORMAT_Z32_UNORM; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (vis->mesa_visual.stencilBits == 8) { 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (depthFormat == PIPE_FORMAT_S8Z24_UNORM) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stencilFormat = depthFormat; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stencilFormat = PIPE_FORMAT_S8_UNORM; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* no stencil */ 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stencilFormat = PIPE_FORMAT_NONE; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (depthFormat == PIPE_FORMAT_S8Z24_UNORM) { 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* use 24-bit Z, undefined stencil channel */ 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) depthFormat = PIPE_FORMAT_X8Z24_UNORM; 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get_drawable_size(vis->display, d, &width, &height); 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create framebuffer, but we'll plug in our own renderbuffers below. 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 39990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) b->stfb = st_create_framebuffer(&vis->mesa_visual, 40090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) colorFormat, depthFormat, stencilFormat, 4018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) width, height, 40290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) (void *) b); 40390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) fb = &b->stfb->Base; 40490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 40590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) /* 40690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * Create scratch XImage for xmesa_display_surface() 40790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) */ 40890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) b->tempImage = XCreateImage(vis->display, 40990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) vis->visinfo->visual, 41090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) vis->visinfo->depth, 41190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ZPixmap, 0, /* format, offset */ 41290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) NULL, /* data */ 41390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 0, 0, /* size */ 41490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 32, /* bitmap_pad */ 41590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 0); /* bytes_per_line */ 41690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 41790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) /* GLX_EXT_texture_from_pixmap */ 41890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) b->TextureTarget = 0; 41990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) b->TextureFormat = GLX_TEXTURE_FORMAT_NONE_EXT; 42090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) b->TextureMipmap = 0; 42190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /* insert buffer into linked list */ 42390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) b->Next = XMesaBufferList; 42490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) XMesaBufferList = b; 42590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 42690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return b; 42790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 42890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 42990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 43090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)/** 43190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * Find an XMesaBuffer by matching X display and colormap but NOT matching 43290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * the notThis buffer. 43390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) */ 43490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)XMesaBuffer 43590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)xmesa_find_buffer(Display *dpy, Colormap cmap, XMesaBuffer notThis) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XMesaBuffer b; 4388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (b = XMesaBufferList; b; b = b->Next) { 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (b->xm_visual->display == dpy && 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b->cmap == cmap && 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b != notThis) { 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return b; 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Remove buffer from linked list, delete if no longer referenced. 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmesa_free_buffer(XMesaBuffer buffer) 4548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles){ 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XMesaBuffer prev = NULL, b; 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (b = XMesaBufferList; b; b = b->Next) { 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (b == buffer) { 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct gl_framebuffer *fb = &buffer->stfb->Base; 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* unlink buffer from list */ 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prev) 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev->Next = buffer->Next; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XMesaBufferList = buffer->Next; 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /* mark as delete pending */ 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fb->DeletePending = GL_TRUE; 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Since the X window for the XMesaBuffer is going away, we don't 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * want to dereference this pointer in the future. 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b->drawable = 0; 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->tempImage->data = NULL; 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XDestroyImage(buffer->tempImage); 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Unreference. If count = zero we'll really delete the buffer */ 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _mesa_reference_framebuffer(&fb, NULL); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XFreeGC(b->xm_visual->display, b->gc); 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(buffer); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* continue search */ 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev = b; 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* buffer not found in XMesaBufferList */ 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _mesa_problem(NULL,"xmesa_free_buffer() - buffer not found\n"); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**********************************************************************/ 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/***** Misc Private Functions *****/ 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**********************************************************************/ 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * When a context is bound for the first time, we can finally finish 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * initializing the context's visual and buffer information. 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \param v the XMesaVisual to initialize 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \param b the XMesaBuffer to initialize (may be NULL) 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \param rgb_flag TRUE = RGBA mode, FALSE = color index mode 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \param window the window/pixmap we're rendering into 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \param cmap the colormap associated with the window/pixmap 50990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * \return GL_TRUE=success, GL_FALSE=failure 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static GLboolean 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b, 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLboolean rgb_flag, Drawable window, 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Colormap cmap) 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT(!b || b->xm_visual == v); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Save true bits/pixel */ 5198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) v->BitsPerPixel = bits_per_pixel(v); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(v->BitsPerPixel > 0); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rgb_flag == GL_FALSE) { 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* COLOR-INDEXED WINDOW: not supported*/ 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GL_FALSE; 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* RGB WINDOW: 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * We support RGB rendering into almost any kind of visual. 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int xclass = v->mesa_visual.visualType; 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xclass != GLX_TRUE_COLOR && xclass == !GLX_DIRECT_COLOR) { 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _mesa_warning(NULL, 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "XMesa: RGB mode rendering not supported in given visual.\n"); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GL_FALSE; 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v->mesa_visual.indexBits = 0; 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (v->BitsPerPixel == 32) { 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* We use XImages for all front/back buffers. If an X Window or 5403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * X Pixmap is 32bpp, there's no guarantee that the alpha channel 541cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * will be preserved. For XImages we're in luck. 542cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 543cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) v->mesa_visual.alphaBits = 8; 544cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 5453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 5463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) /* 5483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * If MESA_INFO env var is set print out some debugging info 5493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * which can help Brian figure out what's going on when a user 5503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * reports bugs. 5513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) */ 5523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (_mesa_getenv("MESA_INFO")) { 5533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) printf("X/Mesa visual = %p\n", (void *) v); 5543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) printf("X/Mesa level = %d\n", v->mesa_visual.level); 5553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) printf("X/Mesa depth = %d\n", v->visinfo->depth); 5563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) printf("X/Mesa bits per pixel = %d\n", v->BitsPerPixel); 5573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 5583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (b && window) { 5603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) /* these should have been set in create_xmesa_buffer */ 5613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ASSERT(b->drawable == window); 5620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 5630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) /* Setup for single/double buffering */ 564 if (v->mesa_visual.doubleBufferMode) { 565 /* Double buffered */ 566 b->shm = xmesa_check_for_xshm( v->display ); 567 } 568 569 /* X11 graphics context */ 570 b->gc = XCreateGC( v->display, window, 0, NULL ); 571 XSetFunction( v->display, b->gc, GXcopy ); 572 } 573 574 return GL_TRUE; 575} 576 577 578 579#define NUM_VISUAL_TYPES 6 580 581/** 582 * Convert an X visual type to a GLX visual type. 583 * 584 * \param visualType X visual type (i.e., \c TrueColor, \c StaticGray, etc.) 585 * to be converted. 586 * \return If \c visualType is a valid X visual type, a GLX visual type will 587 * be returned. Otherwise \c GLX_NONE will be returned. 588 * 589 * \note 590 * This code was lifted directly from lib/GL/glx/glcontextmodes.c in the 591 * DRI CVS tree. 592 */ 593static GLint 594xmesa_convert_from_x_visual_type( int visualType ) 595{ 596 static const int glx_visual_types[ NUM_VISUAL_TYPES ] = { 597 GLX_STATIC_GRAY, GLX_GRAY_SCALE, 598 GLX_STATIC_COLOR, GLX_PSEUDO_COLOR, 599 GLX_TRUE_COLOR, GLX_DIRECT_COLOR 600 }; 601 602 return ( (unsigned) visualType < NUM_VISUAL_TYPES ) 603 ? glx_visual_types[ visualType ] : GLX_NONE; 604} 605 606 607/**********************************************************************/ 608/***** Public Functions *****/ 609/**********************************************************************/ 610 611 612/* 613 * Create a new X/Mesa visual. 614 * Input: display - X11 display 615 * visinfo - an XVisualInfo pointer 616 * rgb_flag - GL_TRUE = RGB mode, 617 * GL_FALSE = color index mode 618 * alpha_flag - alpha buffer requested? 619 * db_flag - GL_TRUE = double-buffered, 620 * GL_FALSE = single buffered 621 * stereo_flag - stereo visual? 622 * ximage_flag - GL_TRUE = use an XImage for back buffer, 623 * GL_FALSE = use an off-screen pixmap for back buffer 624 * depth_size - requested bits/depth values, or zero 625 * stencil_size - requested bits/stencil values, or zero 626 * accum_red_size - requested bits/red accum values, or zero 627 * accum_green_size - requested bits/green accum values, or zero 628 * accum_blue_size - requested bits/blue accum values, or zero 629 * accum_alpha_size - requested bits/alpha accum values, or zero 630 * num_samples - number of samples/pixel if multisampling, or zero 631 * level - visual level, usually 0 632 * visualCaveat - ala the GLX extension, usually GLX_NONE 633 * Return; a new XMesaVisual or 0 if error. 634 */ 635PUBLIC 636XMesaVisual XMesaCreateVisual( Display *display, 637 XVisualInfo * visinfo, 638 GLboolean rgb_flag, 639 GLboolean alpha_flag, 640 GLboolean db_flag, 641 GLboolean stereo_flag, 642 GLboolean ximage_flag, 643 GLint depth_size, 644 GLint stencil_size, 645 GLint accum_red_size, 646 GLint accum_green_size, 647 GLint accum_blue_size, 648 GLint accum_alpha_size, 649 GLint num_samples, 650 GLint level, 651 GLint visualCaveat ) 652{ 653 XMesaVisual v; 654 GLint red_bits, green_bits, blue_bits, alpha_bits; 655 656 /* For debugging only */ 657 if (_mesa_getenv("MESA_XSYNC")) { 658 /* This makes debugging X easier. 659 * In your debugger, set a breakpoint on _XError to stop when an 660 * X protocol error is generated. 661 */ 662 XSynchronize( display, 1 ); 663 } 664 665 v = (XMesaVisual) CALLOC_STRUCT(xmesa_visual); 666 if (!v) { 667 return NULL; 668 } 669 670 v->display = display; 671 672 /* Save a copy of the XVisualInfo struct because the user may Xfree() 673 * the struct but we may need some of the information contained in it 674 * at a later time. 675 */ 676 v->visinfo = (XVisualInfo *) MALLOC(sizeof(*visinfo)); 677 if (!v->visinfo) { 678 free(v); 679 return NULL; 680 } 681 memcpy(v->visinfo, visinfo, sizeof(*visinfo)); 682 683 v->ximage_flag = ximage_flag; 684 685 v->mesa_visual.redMask = visinfo->red_mask; 686 v->mesa_visual.greenMask = visinfo->green_mask; 687 v->mesa_visual.blueMask = visinfo->blue_mask; 688 v->mesa_visual.visualID = visinfo->visualid; 689 v->mesa_visual.screen = visinfo->screen; 690 691#if !(defined(__cplusplus) || defined(c_plusplus)) 692 v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->class); 693#else 694 v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->c_class); 695#endif 696 697 v->mesa_visual.visualRating = visualCaveat; 698 699 if (alpha_flag) 700 v->mesa_visual.alphaBits = 8; 701 702 (void) initialize_visual_and_buffer( v, NULL, rgb_flag, 0, 0 ); 703 704 { 705 const int xclass = v->mesa_visual.visualType; 706 if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) { 707 red_bits = _mesa_bitcount(GET_REDMASK(v)); 708 green_bits = _mesa_bitcount(GET_GREENMASK(v)); 709 blue_bits = _mesa_bitcount(GET_BLUEMASK(v)); 710 } 711 else { 712 /* this is an approximation */ 713 int depth; 714 depth = v->visinfo->depth; 715 red_bits = depth / 3; 716 depth -= red_bits; 717 green_bits = depth / 2; 718 depth -= green_bits; 719 blue_bits = depth; 720 alpha_bits = 0; 721 assert( red_bits + green_bits + blue_bits == v->visinfo->depth ); 722 } 723 alpha_bits = v->mesa_visual.alphaBits; 724 } 725 726 _mesa_initialize_visual( &v->mesa_visual, 727 rgb_flag, db_flag, stereo_flag, 728 red_bits, green_bits, 729 blue_bits, alpha_bits, 730 v->mesa_visual.indexBits, 731 depth_size, 732 stencil_size, 733 accum_red_size, accum_green_size, 734 accum_blue_size, accum_alpha_size, 735 0 ); 736 737 /* XXX minor hack */ 738 v->mesa_visual.level = level; 739 return v; 740} 741 742 743PUBLIC 744void XMesaDestroyVisual( XMesaVisual v ) 745{ 746 free(v->visinfo); 747 free(v); 748} 749 750 751 752/** 753 * Create a new XMesaContext. 754 * \param v the XMesaVisual 755 * \param share_list another XMesaContext with which to share display 756 * lists or NULL if no sharing is wanted. 757 * \return an XMesaContext or NULL if error. 758 */ 759PUBLIC 760XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) 761{ 762 static GLboolean firstTime = GL_TRUE; 763 struct pipe_context *pipe = NULL; 764 XMesaContext c; 765 GLcontext *mesaCtx; 766 uint pf; 767 768 if (firstTime) { 769 pipe_mutex_init(_xmesa_lock); 770 _screen = driver.create_pipe_screen(); 771 screen = trace_screen_create( _screen ); 772 firstTime = GL_FALSE; 773 } 774 775 /* Note: the XMesaContext contains a Mesa GLcontext struct (inheritance) */ 776 c = (XMesaContext) CALLOC_STRUCT(xmesa_context); 777 if (!c) 778 return NULL; 779 780 pf = choose_pixel_format(v); 781 assert(pf); 782 783 c->xm_visual = v; 784 c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */ 785 c->xm_read_buffer = NULL; 786 787 if (screen == NULL) 788 goto fail; 789 790 /* Trace screen knows how to properly wrap context creation in the 791 * wrapped screen, so nothing special to do here: 792 */ 793 pipe = screen->context_create(screen, (void *) c); 794 if (pipe == NULL) 795 goto fail; 796 797 c->st = st_create_context(pipe, 798 &v->mesa_visual, 799 share_list ? share_list->st : NULL); 800 if (c->st == NULL) 801 goto fail; 802 803 mesaCtx = c->st->ctx; 804 c->st->ctx->DriverCtx = c; 805 806 return c; 807 808fail: 809 if (c->st) 810 st_destroy_context(c->st); 811 else if (pipe) 812 pipe->destroy(pipe); 813 814 free(c); 815 return NULL; 816} 817 818 819 820PUBLIC 821void XMesaDestroyContext( XMesaContext c ) 822{ 823 st_destroy_context(c->st); 824 825 /* FIXME: We should destroy the screen here, but if we do so, surfaces may 826 * outlive it, causing segfaults 827 struct pipe_screen *screen = c->st->pipe->screen; 828 screen->destroy(screen); 829 */ 830 831 free(c); 832} 833 834 835 836/** 837 * Private function for creating an XMesaBuffer which corresponds to an 838 * X window or pixmap. 839 * \param v the window's XMesaVisual 840 * \param w the window we're wrapping 841 * \return new XMesaBuffer or NULL if error 842 */ 843PUBLIC XMesaBuffer 844XMesaCreateWindowBuffer(XMesaVisual v, Window w) 845{ 846 XWindowAttributes attr; 847 XMesaBuffer b; 848 Colormap cmap; 849 int depth; 850 851 assert(v); 852 assert(w); 853 854 /* Check that window depth matches visual depth */ 855 XGetWindowAttributes( v->display, w, &attr ); 856 depth = attr.depth; 857 if (v->visinfo->depth != depth) { 858 _mesa_warning(NULL, "XMesaCreateWindowBuffer: depth mismatch between visual (%d) and window (%d)!\n", 859 v->visinfo->depth, depth); 860 return NULL; 861 } 862 863 /* Find colormap */ 864 if (attr.colormap) { 865 cmap = attr.colormap; 866 } 867 else { 868 _mesa_warning(NULL, "Window %u has no colormap!\n", (unsigned int) w); 869 /* this is weird, a window w/out a colormap!? */ 870 /* OK, let's just allocate a new one and hope for the best */ 871 cmap = XCreateColormap(v->display, w, attr.visual, AllocNone); 872 } 873 874 b = create_xmesa_buffer((Drawable) w, WINDOW, v, cmap); 875 if (!b) 876 return NULL; 877 878 if (!initialize_visual_and_buffer( v, b, v->mesa_visual.rgbMode, 879 (Drawable) w, cmap )) { 880 xmesa_free_buffer(b); 881 return NULL; 882 } 883 884 return b; 885} 886 887 888 889/** 890 * Create a new XMesaBuffer from an X pixmap. 891 * 892 * \param v the XMesaVisual 893 * \param p the pixmap 894 * \param cmap the colormap, may be 0 if using a \c GLX_TRUE_COLOR or 895 * \c GLX_DIRECT_COLOR visual for the pixmap 896 * \returns new XMesaBuffer or NULL if error 897 */ 898PUBLIC XMesaBuffer 899XMesaCreatePixmapBuffer(XMesaVisual v, Pixmap p, Colormap cmap) 900{ 901 XMesaBuffer b; 902 903 assert(v); 904 905 b = create_xmesa_buffer((Drawable) p, PIXMAP, v, cmap); 906 if (!b) 907 return NULL; 908 909 if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode, 910 (Drawable) p, cmap)) { 911 xmesa_free_buffer(b); 912 return NULL; 913 } 914 915 return b; 916} 917 918 919/** 920 * For GLX_EXT_texture_from_pixmap 921 */ 922XMesaBuffer 923XMesaCreatePixmapTextureBuffer(XMesaVisual v, Pixmap p, 924 Colormap cmap, 925 int format, int target, int mipmap) 926{ 927 GET_CURRENT_CONTEXT(ctx); 928 XMesaBuffer b; 929 GLuint width, height; 930 931 assert(v); 932 933 b = create_xmesa_buffer((Drawable) p, PIXMAP, v, cmap); 934 if (!b) 935 return NULL; 936 937 /* get pixmap size, update framebuffer/renderbuffer dims */ 938 xmesa_get_window_size(v->display, b, &width, &height); 939 _mesa_resize_framebuffer(NULL, &(b->stfb->Base), width, height); 940 941 if (target == 0) { 942 /* examine dims */ 943 if (ctx->Extensions.ARB_texture_non_power_of_two) { 944 target = GLX_TEXTURE_2D_EXT; 945 } 946 else if ( _mesa_bitcount(width) == 1 947 && _mesa_bitcount(height) == 1) { 948 /* power of two size */ 949 if (height == 1) { 950 target = GLX_TEXTURE_1D_EXT; 951 } 952 else { 953 target = GLX_TEXTURE_2D_EXT; 954 } 955 } 956 else if (ctx->Extensions.NV_texture_rectangle) { 957 target = GLX_TEXTURE_RECTANGLE_EXT; 958 } 959 else { 960 /* non power of two textures not supported */ 961 XMesaDestroyBuffer(b); 962 return 0; 963 } 964 } 965 966 b->TextureTarget = target; 967 b->TextureFormat = format; 968 b->TextureMipmap = mipmap; 969 970 if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode, 971 (Drawable) p, cmap)) { 972 xmesa_free_buffer(b); 973 return NULL; 974 } 975 976 return b; 977} 978 979 980 981XMesaBuffer 982XMesaCreatePBuffer(XMesaVisual v, Colormap cmap, 983 unsigned int width, unsigned int height) 984{ 985 Window root; 986 Drawable drawable; /* X Pixmap Drawable */ 987 XMesaBuffer b; 988 989 /* allocate pixmap for front buffer */ 990 root = RootWindow( v->display, v->visinfo->screen ); 991 drawable = XCreatePixmap(v->display, root, width, height, 992 v->visinfo->depth); 993 if (!drawable) 994 return NULL; 995 996 b = create_xmesa_buffer(drawable, PBUFFER, v, cmap); 997 if (!b) 998 return NULL; 999 1000 if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode, 1001 drawable, cmap)) { 1002 xmesa_free_buffer(b); 1003 return NULL; 1004 } 1005 1006 return b; 1007} 1008 1009 1010 1011/* 1012 * Deallocate an XMesaBuffer structure and all related info. 1013 */ 1014PUBLIC void 1015XMesaDestroyBuffer(XMesaBuffer b) 1016{ 1017 xmesa_free_buffer(b); 1018} 1019 1020 1021/** 1022 * Query the current window size and update the corresponding GLframebuffer 1023 * and all attached renderbuffers. 1024 * Called when: 1025 * 1. the first time a buffer is bound to a context. 1026 * 2. SwapBuffers. XXX probabaly from xm_flush_frontbuffer() too... 1027 * Note: it's possible (and legal) for xmctx to be NULL. That can happen 1028 * when resizing a buffer when no rendering context is bound. 1029 */ 1030void 1031xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer) 1032{ 1033 GLuint width, height; 1034 xmesa_get_window_size(drawBuffer->xm_visual->display, drawBuffer, &width, &height); 1035 st_resize_framebuffer(drawBuffer->stfb, width, height); 1036} 1037 1038 1039 1040 1041/* 1042 * Bind buffer b to context c and make c the current rendering context. 1043 */ 1044PUBLIC 1045GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer, 1046 XMesaBuffer readBuffer ) 1047{ 1048 XMesaContext old_ctx = XMesaGetCurrentContext(); 1049 1050 if (old_ctx && old_ctx != c) { 1051 XMesaFlush(old_ctx); 1052 old_ctx->xm_buffer = NULL; 1053 old_ctx->xm_read_buffer = NULL; 1054 } 1055 1056 if (c) { 1057 if (!drawBuffer || !readBuffer) 1058 return GL_FALSE; /* must specify buffers! */ 1059 1060 if (c == old_ctx && 1061 c->xm_buffer == drawBuffer && 1062 c->xm_read_buffer == readBuffer) 1063 return GL_TRUE; 1064 1065 c->xm_buffer = drawBuffer; 1066 c->xm_read_buffer = readBuffer; 1067 1068 st_make_current(c->st, drawBuffer->stfb, readBuffer->stfb); 1069 1070 xmesa_check_and_update_buffer_size(c, drawBuffer); 1071 if (readBuffer != drawBuffer) 1072 xmesa_check_and_update_buffer_size(c, readBuffer); 1073 1074 /* Solution to Stephane Rehel's problem with glXReleaseBuffersMESA(): */ 1075 drawBuffer->wasCurrent = GL_TRUE; 1076 } 1077 else { 1078 /* Detach */ 1079 st_make_current( NULL, NULL, NULL ); 1080 1081 } 1082 return GL_TRUE; 1083} 1084 1085 1086/* 1087 * Unbind the context c from its buffer. 1088 */ 1089GLboolean XMesaUnbindContext( XMesaContext c ) 1090{ 1091 /* A no-op for XFree86 integration purposes */ 1092 return GL_TRUE; 1093} 1094 1095 1096XMesaContext XMesaGetCurrentContext( void ) 1097{ 1098 GET_CURRENT_CONTEXT(ctx); 1099 if (ctx) { 1100 XMesaContext xmesa = xmesa_context(ctx); 1101 return xmesa; 1102 } 1103 else { 1104 return 0; 1105 } 1106} 1107 1108 1109 1110/** 1111 * Swap front and back color buffers and have winsys display front buffer. 1112 * If there's no front color buffer no swap actually occurs. 1113 */ 1114PUBLIC 1115void XMesaSwapBuffers( XMesaBuffer b ) 1116{ 1117 struct pipe_surface *frontLeftSurf; 1118 1119 st_swapbuffers(b->stfb, &frontLeftSurf, NULL); 1120 1121 if (frontLeftSurf) { 1122 if (_screen != screen) { 1123 struct trace_surface *tr_surf = trace_surface( frontLeftSurf ); 1124 struct pipe_surface *surf = tr_surf->surface; 1125 frontLeftSurf = surf; 1126 } 1127 1128 driver.display_surface(b, frontLeftSurf); 1129 } 1130 1131 xmesa_check_and_update_buffer_size(NULL, b); 1132} 1133 1134 1135 1136/* 1137 * Copy sub-region of back buffer to front buffer 1138 */ 1139void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height ) 1140{ 1141 struct pipe_surface *surf_front; 1142 struct pipe_surface *surf_back; 1143 struct pipe_context *pipe = NULL; /* XXX fix */ 1144 1145 st_get_framebuffer_surface(b->stfb, ST_SURFACE_FRONT_LEFT, &surf_front); 1146 st_get_framebuffer_surface(b->stfb, ST_SURFACE_BACK_LEFT, &surf_back); 1147 1148 if (!surf_front || !surf_back) 1149 return; 1150 1151 assert(pipe); 1152 pipe->surface_copy(pipe, 1153 surf_front, x, y, /* dest */ 1154 surf_back, x, y, /* src */ 1155 width, height); 1156} 1157 1158 1159 1160void XMesaFlush( XMesaContext c ) 1161{ 1162 if (c && c->xm_visual->display) { 1163 st_finish(c->st); 1164 XSync( c->xm_visual->display, False ); 1165 } 1166} 1167 1168 1169 1170 1171 1172XMesaBuffer XMesaFindBuffer( Display *dpy, Drawable d ) 1173{ 1174 XMesaBuffer b; 1175 for (b = XMesaBufferList; b; b = b->Next) { 1176 if (b->drawable == d && b->xm_visual->display == dpy) { 1177 return b; 1178 } 1179 } 1180 return NULL; 1181} 1182 1183 1184/** 1185 * Free/destroy all XMesaBuffers associated with given display. 1186 */ 1187void xmesa_destroy_buffers_on_display(Display *dpy) 1188{ 1189 XMesaBuffer b, next; 1190 for (b = XMesaBufferList; b; b = next) { 1191 next = b->Next; 1192 if (b->xm_visual->display == dpy) { 1193 xmesa_free_buffer(b); 1194 } 1195 } 1196} 1197 1198 1199/* 1200 * Look for XMesaBuffers whose X window has been destroyed. 1201 * Deallocate any such XMesaBuffers. 1202 */ 1203void XMesaGarbageCollect( void ) 1204{ 1205 XMesaBuffer b, next; 1206 for (b=XMesaBufferList; b; b=next) { 1207 next = b->Next; 1208 if (b->xm_visual && 1209 b->xm_visual->display && 1210 b->drawable && 1211 b->type == WINDOW) { 1212 XSync(b->xm_visual->display, False); 1213 if (!window_exists( b->xm_visual->display, b->drawable )) { 1214 /* found a dead window, free the ancillary info */ 1215 XMesaDestroyBuffer( b ); 1216 } 1217 } 1218 } 1219} 1220 1221 1222 1223 1224PUBLIC void 1225XMesaBindTexImage(Display *dpy, XMesaBuffer drawable, int buffer, 1226 const int *attrib_list) 1227{ 1228} 1229 1230 1231 1232PUBLIC void 1233XMesaReleaseTexImage(Display *dpy, XMesaBuffer drawable, int buffer) 1234{ 1235} 1236 1237