xm_api.c revision e0e993c5ff090058037875642dcd34727a3d8760
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Mesa 3-D graphics library 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Version: 6.3 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Permission is hereby granted, free of charge, to any person obtaining a 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * copy of this software and associated documentation files (the "Software"), 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to deal in the Software without restriction, including without limitation 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the rights to use, copy, modify, merge, publish, distribute, sublicense, 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and/or sell copies of the Software, and to permit persons to whom the 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Software is furnished to do so, subject to the following conditions: 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The above copyright notice and this permission notice shall be included 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in all copies or substantial portions of the Software. 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This file contains the implementations of all the XMesa* functions. 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * NOTES: 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The window coordinate system origin (0,0) is in the lower-left corner 32b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen * of the window. X11's window coordinate origin is in the upper-left 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * corner of the window. Therefore, most drawing functions in this 34b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen * file have to flip Y coordinates. 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 36b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen * Define USE_XSHM in the Makefile with -DUSE_XSHM if you want to compile 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in support for the MIT Shared Memory extension. If enabled, when you 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * use an Ximage for the back buffer in double buffered mode, the "swap" 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * operation will be faster. You must also link with -lXext. 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Byte swapping: If the Mesa host and the X display use a different 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * byte order then there's some trickiness to be aware of when using 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * XImages. The byte ordering used for the XImage is that of the X 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * display, not the Mesa host. 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The color-to-pixel encoding for True/DirectColor must be done 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * according to the display's visual red_mask, green_mask, and blue_mask. 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If XPutPixel is used to put a pixel into an XImage then XPutPixel will 48b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen * do byte swapping if needed. If one wants to directly "poke" the pixel 4930c918ce7fbe171944b28fc91b3f22b3d631872dGlenn Kasten * into the XImage's buffer then the pixel must be byte swapped first. In 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Mesa, when byte swapping is needed we use the PF_TRUECOLOR pixel format 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and use XPutPixel everywhere except in the implementation of 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * glClear(GL_COLOR_BUFFER_BIT). We want this function to be fast so 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * instead of using XPutPixel we "poke" our values after byte-swapping 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the clear pixel value if needed. 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef __CYGWIN__ 59e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn#undef WIN32 60e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn#undef __WIN32__ 61e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn#endif 62b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen 63e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn#include "glxheader.h" 64e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn#include "GL/xmesa.h" 65e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn#include "xmesaP.h" 66e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn#include "context.h" 67b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen#include "extensions.h" 68b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen#include "framebuffer.h" 69b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen#include "glthread.h" 70e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn#include "imports.h" 71e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn#include "matrix.h" 72b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen#include "mtypes.h" 73e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn#include "macros.h" 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "renderbuffer.h" 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "texformat.h" 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "texobj.h" 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "texstore.h" 78b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen#include "swrast/swrast.h" 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "swrast_setup/swrast_setup.h" 80b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen#include "array_cache/acache.h" 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "tnl/tnl.h" 82b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen#include "tnl/t_context.h" 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "tnl/t_pipeline.h" 84b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen#if 0 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "drivers/common/driverfuncs.h" 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef XFree86Server 89b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen#include <GL/glxtokens.h> 90b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen#endif 91b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Global X driver lock 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project_glthread_Mutex _xmesa_lock; 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Lookup tables for HPCR pixel format: 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic short hpcr_rgbTbl[3][256] = { 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 116f7bcf1951c598604d312600d1efe5734646dc5a4Marco Nelissen176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 117f7bcf1951c598604d312600d1efe5734646dc5a4Marco Nelissen192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 118f7bcf1951c598604d312600d1efe5734646dc5a4Marco Nelissen208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}, 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 13143a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 13743a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}, 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47, 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63, 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 64, 64, 65, 65, 66, 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 145b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen 72, 72, 73, 73, 74, 74, 75, 75, 76, 76, 77, 77, 78, 78, 79, 79, 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 80, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, 86, 86, 87, 87, 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223 156b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen} 157e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn}; 158b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**********************************************************************/ 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/***** X Utility Functions *****/ 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**********************************************************************/ 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the host's byte order as LSBFirst or MSBFirst ala X. 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 16943a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato#ifndef XFree86Server 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int host_byte_order( void ) 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i = 1; 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char *cptr = (char *) &i; 17443a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato return (*cptr==1) ? LSBFirst : MSBFirst; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 180b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen * Error handling. 181e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn */ 182e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn#ifndef XFree86Server 183e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackbornstatic volatile int mesaXErrorFlag = 0; 184b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen 185e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackbornstatic int mesaHandleXError( XMesaDisplay *dpy, XErrorEvent *event ) 186e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn{ 187b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen (void) dpy; 188b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen (void) event; 189e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn mesaXErrorFlag = 1; 190e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn return 0; 191e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn} 192e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn#endif 193b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen 194e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn 195e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn/* 196e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn * Check if the X Shared Memory extension is available. 197b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen * Return: 0 = not available 198e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn * 1 = shared XImage support available 199e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn * 2 = shared Pixmap support available also 200e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn */ 201e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn#ifndef XFree86Server 202e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackbornstatic int check_for_xshm( XMesaDisplay *display ) 203e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn{ 204b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen#ifdef USE_XSHM 205e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn int major, minor, ignore; 206e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn Bool pixmaps; 207e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn 208e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) { 209e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) { 210e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn return (pixmaps==True) ? 2 : 1; 211e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn } 212e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn else { 213e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn return 0; 214e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn } 215b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen } 216e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn else { 217e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn return 0; 218e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn } 219e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn#else 220e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn /* Can't compile XSHM support */ 221e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn return 0; 222e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn#endif 223b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen} 224e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn#endif 225e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn 226e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn 227e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn/* 228e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn * Apply gamma correction to an intensity value in [0..max]. Return the 229e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn * new intensity value. 230e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn */ 2311e88cf0796c8b15952b7d6b3160d0d097e857f15Ryan Lothianstatic GLint gamma_adjust( GLfloat gamma, GLint value, GLint max ) 232e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn{ 233e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn if (gamma == 1.0) { 234b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen return value; 235e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn } 236e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn else { 237e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn double x = (double) value / (double) max; 238e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn return IROUND_POS((GLfloat) max * _mesa_pow(x, 1.0F/gamma)); 239e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn } 240b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen} 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 24543a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato * Return the true number of bits per pixel for XImages. 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For example, if we request a 24-bit deep visual we may actually need/get 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 32bpp XImages. This function returns the appropriate bpp. 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Input: dpy - the X display 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * visinfo - desribes the visual to be used for XImages 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return: true number of bits per pixel for XImages 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef XFree86Server 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int bits_per_pixel( XMesaVisual xmv ) 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int depth = xmv->nplanes; 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i; 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i = 0; i < screenInfo.numPixmapFormats; i++) { 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (screenInfo.formats[i].depth == depth) 26043a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato return screenInfo.formats[i].bitsPerPixel; 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return depth; /* should never get here, but this should be safe */ 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int bits_per_pixel( XMesaVisual xmv ) 268{ 269 XMesaDisplay *dpy = xmv->display; 270 XMesaVisualInfo visinfo = xmv->visinfo; 271 XMesaImage *img; 272 int bitsPerPixel; 273 /* Create a temporary XImage */ 274 img = XCreateImage( dpy, visinfo->visual, visinfo->depth, 275 ZPixmap, 0, /*format, offset*/ 276 (char*) MALLOC(8), /*data*/ 277 1, 1, /*width, height*/ 278 32, /*bitmap_pad*/ 279 0 /*bytes_per_line*/ 280 ); 281 assert(img); 282 /* grab the bits/pixel value */ 283 bitsPerPixel = img->bits_per_pixel; 284 /* free the XImage */ 285 _mesa_free( img->data ); 286 img->data = NULL; 287 XMesaDestroyImage( img ); 288 return bitsPerPixel; 289} 290#endif 291 292 293 294/* 295 * Determine if a given X window ID is valid (window exists). 296 * Do this by calling XGetWindowAttributes() for the window and 297 * checking if we catch an X error. 298 * Input: dpy - the display 299 * win - the window to check for existance 300 * Return: GL_TRUE - window exists 301 * GL_FALSE - window doesn't exist 302 */ 303#ifndef XFree86Server 304static GLboolean WindowExistsFlag; 305 306static int window_exists_err_handler( XMesaDisplay* dpy, XErrorEvent* xerr ) 307{ 308 (void) dpy; 309 if (xerr->error_code == BadWindow) { 310 WindowExistsFlag = GL_FALSE; 311 } 312 return 0; 313} 314 315static GLboolean window_exists( XMesaDisplay *dpy, Window win ) 316{ 317 XWindowAttributes wa; 318 int (*old_handler)( XMesaDisplay*, XErrorEvent* ); 319 WindowExistsFlag = GL_TRUE; 320 old_handler = XSetErrorHandler(window_exists_err_handler); 321 XGetWindowAttributes( dpy, win, &wa ); /* dummy request */ 322 XSetErrorHandler(old_handler); 323 return WindowExistsFlag; 324} 325#endif 326 327 328 329/**********************************************************************/ 330/***** Linked list of XMesaBuffers *****/ 331/**********************************************************************/ 332 333static XMesaBuffer XMesaBufferList = NULL; 334 335 336/** 337 * Allocate a new XMesaBuffer, initialize basic fields and add to 338 * the list of all buffers. 339 */ 340static XMesaBuffer 341alloc_xmesa_buffer(XMesaVisual vis, BufferType type, XMesaColormap cmap) 342{ 343 XMesaBuffer b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer); 344 if (b) { 345 b->display = vis->display; 346 b->xm_visual = vis; 347 b->type = type; 348 b->cmap = cmap; 349 350 _mesa_initialize_framebuffer(&b->mesa_buffer, &vis->mesa_visual); 351 352 /* determine back buffer implementation */ 353 if (vis->mesa_visual.doubleBufferMode) { 354 if (vis->ximage_flag) { 355 b->db_state = BACK_XIMAGE; 356 } 357 else { 358 b->db_state = BACK_PIXMAP; 359 } 360 } 361 else { 362 b->db_state = 0; 363 } 364 365 /* Allocate the framebuffer's renderbuffers */ 366 assert(!b->mesa_buffer.Attachment[BUFFER_FRONT_LEFT].Renderbuffer); 367 assert(!b->mesa_buffer.Attachment[BUFFER_BACK_LEFT].Renderbuffer); 368 369 /* front renderbuffer */ 370 b->frontxrb = xmesa_new_renderbuffer(NULL, 0, vis->mesa_visual.rgbMode); 371 _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_FRONT_LEFT, 372 &b->frontxrb->Base); 373 374 /* back renderbuffer */ 375 if (vis->mesa_visual.doubleBufferMode) { 376 b->backxrb =xmesa_new_renderbuffer(NULL, 0, vis->mesa_visual.rgbMode); 377 _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_BACK_LEFT, 378 &b->backxrb->Base); 379 } 380 381 _mesa_add_soft_renderbuffers(&b->mesa_buffer, 382 GL_FALSE, /* color */ 383 vis->mesa_visual.haveDepthBuffer, 384 vis->mesa_visual.haveStencilBuffer, 385 vis->mesa_visual.haveAccumBuffer, 386 vis->mesa_visual.alphaBits > 0, 387 vis->mesa_visual.numAuxBuffers > 0 ); 388 389 /* insert into linked list */ 390 b->Next = XMesaBufferList; 391 XMesaBufferList = b; 392 } 393 return b; 394} 395 396 397/* 398 * Find an XMesaBuffer by matching X display and colormap but NOT matching 399 * the notThis buffer. 400 */ 401static XMesaBuffer find_xmesa_buffer(XMesaDisplay *dpy, 402 XMesaColormap cmap, 403 XMesaBuffer notThis) 404{ 405 XMesaBuffer b; 406 for (b=XMesaBufferList; b; b=b->Next) { 407 if (b->display==dpy && b->cmap==cmap && b!=notThis) { 408 return b; 409 } 410 } 411 return NULL; 412} 413 414 415/* 416 * Free an XMesaBuffer, remove from linked list, perhaps free X colormap 417 * entries. 418 */ 419static void free_xmesa_buffer(int client, XMesaBuffer buffer) 420{ 421 XMesaBuffer prev = NULL, b; 422 (void) client; 423 for (b=XMesaBufferList; b; b=b->Next) { 424 if (b==buffer) { 425 /* unlink bufer from list */ 426 if (prev) 427 prev->Next = buffer->Next; 428 else 429 XMesaBufferList = buffer->Next; 430 /* Check to free X colors */ 431 if (buffer->num_alloced>0) { 432 /* If no other buffer uses this X colormap then free the colors. */ 433 if (!find_xmesa_buffer(buffer->display, buffer->cmap, buffer)) { 434#ifdef XFree86Server 435 (void)FreeColors(buffer->cmap, client, 436 buffer->num_alloced, buffer->alloced_colors, 437 0); 438#else 439 XFreeColors(buffer->display, buffer->cmap, 440 buffer->alloced_colors, buffer->num_alloced, 0); 441#endif 442 } 443 } 444 445 _mesa_free_framebuffer_data(&buffer->mesa_buffer); 446 /* delete front/back renderbuffers */ 447 buffer->frontxrb->Base.Delete(&(buffer->frontxrb->Base)); 448 if (buffer->backxrb) 449 buffer->backxrb->Base.Delete(&(buffer->backxrb->Base)); 450 _mesa_free(buffer); 451 452 return; 453 } 454 /* continue search */ 455 prev = b; 456 } 457 /* buffer not found in XMesaBufferList */ 458 _mesa_problem(NULL,"free_xmesa_buffer() - buffer not found\n"); 459} 460 461 462/* Copy X color table stuff from one XMesaBuffer to another. */ 463static void copy_colortable_info(XMesaBuffer dst, const XMesaBuffer src) 464{ 465 MEMCPY(dst->color_table, src->color_table, sizeof(src->color_table)); 466 MEMCPY(dst->pixel_to_r, src->pixel_to_r, sizeof(src->pixel_to_r)); 467 MEMCPY(dst->pixel_to_g, src->pixel_to_g, sizeof(src->pixel_to_g)); 468 MEMCPY(dst->pixel_to_b, src->pixel_to_b, sizeof(src->pixel_to_b)); 469 dst->num_alloced = src->num_alloced; 470 MEMCPY(dst->alloced_colors, src->alloced_colors, 471 sizeof(src->alloced_colors)); 472} 473 474 475 476/**********************************************************************/ 477/***** Misc Private Functions *****/ 478/**********************************************************************/ 479 480 481/* 482 * Return number of bits set in n. 483 */ 484static int bitcount( unsigned long n ) 485{ 486 int bits; 487 for (bits=0; n>0; n=n>>1) { 488 if (n&1) { 489 bits++; 490 } 491 } 492 return bits; 493} 494 495 496 497/** 498 * Allocate a shared memory XImage back buffer for the given XMesaBuffer. 499 * Return: GL_TRUE if success, GL_FALSE if error 500 */ 501#ifndef XFree86Server 502static GLboolean 503alloc_shm_back_buffer(XMesaBuffer b, GLuint width, GLuint height) 504{ 505#ifdef USE_XSHM 506 /* 507 * We have to do a _lot_ of error checking here to be sure we can 508 * really use the XSHM extension. It seems different servers trigger 509 * errors at different points if the extension won't work. Therefore 510 * we have to be very careful... 511 */ 512 GC gc; 513 int (*old_handler)( XMesaDisplay *, XErrorEvent * ); 514 515 if (width == 0 || height == 0) { 516 /* this will be true the first time we're called on 'b' */ 517 return GL_FALSE; 518 } 519 520 b->backxrb->ximage = XShmCreateImage(b->xm_visual->display, 521 b->xm_visual->visinfo->visual, 522 b->xm_visual->visinfo->depth, 523 ZPixmap, NULL, &b->shminfo, 524 width, height); 525 if (b->backxrb->ximage == NULL) { 526 _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (XShmCreateImage), disabling."); 527 b->shm = 0; 528 return GL_FALSE; 529 } 530 531 b->shminfo.shmid = shmget( IPC_PRIVATE, b->backxrb->ximage->bytes_per_line 532 * b->backxrb->ximage->height, IPC_CREAT|0777 ); 533 if (b->shminfo.shmid < 0) { 534 _mesa_warning(NULL, "shmget failed while allocating back buffer"); 535 XDestroyImage( b->backxrb->ximage ); 536 b->backxrb->ximage = NULL; 537 _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmget), disabling."); 538 b->shm = 0; 539 return GL_FALSE; 540 } 541 542 b->shminfo.shmaddr = b->backxrb->ximage->data 543 = (char*)shmat( b->shminfo.shmid, 0, 0 ); 544 if (b->shminfo.shmaddr == (char *) -1) { 545 _mesa_warning(NULL, "shmat() failed while allocating back buffer"); 546 XDestroyImage( b->backxrb->ximage ); 547 shmctl( b->shminfo.shmid, IPC_RMID, 0 ); 548 b->backxrb->ximage = NULL; 549 _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmat), disabling."); 550 b->shm = 0; 551 return GL_FALSE; 552 } 553 554 b->shminfo.readOnly = False; 555 mesaXErrorFlag = 0; 556 old_handler = XSetErrorHandler( mesaHandleXError ); 557 /* This may trigger the X protocol error we're ready to catch: */ 558 XShmAttach( b->xm_visual->display, &b->shminfo ); 559 XSync( b->xm_visual->display, False ); 560 561 if (mesaXErrorFlag) { 562 /* we are on a remote display, this error is normal, don't print it */ 563 XFlush( b->xm_visual->display ); 564 mesaXErrorFlag = 0; 565 XDestroyImage( b->backxrb->ximage ); 566 shmdt( b->shminfo.shmaddr ); 567 shmctl( b->shminfo.shmid, IPC_RMID, 0 ); 568 b->backxrb->ximage = NULL; 569 b->shm = 0; 570 (void) XSetErrorHandler( old_handler ); 571 return GL_FALSE; 572 } 573 574 shmctl( b->shminfo.shmid, IPC_RMID, 0 ); /* nobody else needs it */ 575 576 /* Finally, try an XShmPutImage to be really sure the extension works */ 577 gc = XCreateGC( b->xm_visual->display, b->frontxrb->pixmap, 0, NULL ); 578 XShmPutImage( b->xm_visual->display, b->frontxrb->pixmap, gc, 579 b->backxrb->ximage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False ); 580 XSync( b->xm_visual->display, False ); 581 XFreeGC( b->xm_visual->display, gc ); 582 (void) XSetErrorHandler( old_handler ); 583 if (mesaXErrorFlag) { 584 XFlush( b->xm_visual->display ); 585 mesaXErrorFlag = 0; 586 XDestroyImage( b->backxrb->ximage ); 587 shmdt( b->shminfo.shmaddr ); 588 shmctl( b->shminfo.shmid, IPC_RMID, 0 ); 589 b->backxrb->ximage = NULL; 590 b->shm = 0; 591 return GL_FALSE; 592 } 593 594 return GL_TRUE; 595#else 596 /* Can't compile XSHM support */ 597 return GL_FALSE; 598#endif 599} 600#endif 601 602 603 604/* 605 * Setup an off-screen pixmap or Ximage to use as the back buffer. 606 * Input: b - the X/Mesa buffer 607 */ 608void 609xmesa_alloc_back_buffer( XMesaBuffer b, GLuint width, GLuint height ) 610{ 611 if (width == 0 || height == 0) 612 return; 613 614 if (b->db_state == BACK_XIMAGE) { 615 /* Deallocate the old backxrb->ximage, if any */ 616 if (b->backxrb->ximage) { 617#if defined(USE_XSHM) && !defined(XFree86Server) 618 if (b->shm) { 619 XShmDetach( b->xm_visual->display, &b->shminfo ); 620 XDestroyImage( b->backxrb->ximage ); 621 shmdt( b->shminfo.shmaddr ); 622 } 623 else 624#endif 625 XMesaDestroyImage( b->backxrb->ximage ); 626 b->backxrb->ximage = NULL; 627 } 628 629 /* Allocate new back buffer */ 630#ifdef XFree86Server 631 { 632 /* Allocate a regular XImage for the back buffer. */ 633 b->backxrb->ximage = XMesaCreateImage(b->xm_visual->BitsPerPixel, 634 width, height, NULL); 635#else 636 if (b->shm == 0 || !alloc_shm_back_buffer(b, width, height)) { 637 /* Allocate a regular XImage for the back buffer. */ 638 b->backxrb->ximage = XCreateImage( b->xm_visual->display, 639 b->xm_visual->visinfo->visual, 640 GET_VISUAL_DEPTH(b->xm_visual), 641 ZPixmap, 0, /* format, offset */ 642 NULL, 643 width, height, 644 8, 0 ); /* pad, bytes_per_line */ 645#endif 646 if (!b->backxrb->ximage) { 647 _mesa_warning(NULL, "alloc_back_buffer: XCreateImage failed."); 648 } 649 b->backxrb->ximage->data = (char *) MALLOC( b->backxrb->ximage->height 650 * b->backxrb->ximage->bytes_per_line ); 651 if (!b->backxrb->ximage->data) { 652 _mesa_warning(NULL, "alloc_back_buffer: MALLOC failed."); 653 XMesaDestroyImage( b->backxrb->ximage ); 654 b->backxrb->ximage = NULL; 655 } 656 } 657 b->backxrb->pixmap = None; 658 b->backxrb->ximage = b->backxrb->ximage; 659 } 660 else if (b->db_state==BACK_PIXMAP) { 661 if (!width) 662 width = 1; 663 if (!height) 664 height = 1; 665 666 /* Free the old back pixmap */ 667 if (b->backxrb->pixmap) { 668 XMesaFreePixmap( b->xm_visual->display, b->backxrb->pixmap ); 669 } 670 /* Allocate new back pixmap */ 671 b->backxrb->pixmap = XMesaCreatePixmap( b->xm_visual->display, b->frontxrb->pixmap, 672 width, height, 673 GET_VISUAL_DEPTH(b->xm_visual) ); 674 b->backxrb->ximage = NULL; 675 } 676} 677 678 679 680/* 681 * A replacement for XAllocColor. This function should never 682 * fail to allocate a color. When XAllocColor fails, we return 683 * the nearest matching color. If we have to allocate many colors 684 * this function isn't too efficient; the XQueryColors() could be 685 * done just once. 686 * Written by Michael Pichler, Brian Paul, Mark Kilgard 687 * Input: dpy - X display 688 * cmap - X colormap 689 * cmapSize - size of colormap 690 * In/Out: color - the XColor struct 691 * Output: exact - 1=exact color match, 0=closest match 692 * alloced - 1=XAlloc worked, 0=XAlloc failed 693 */ 694static void 695noFaultXAllocColor( int client, 696 XMesaDisplay *dpy, 697 XMesaColormap cmap, 698 int cmapSize, 699 XMesaColor *color, 700 int *exact, int *alloced ) 701{ 702#ifdef XFree86Server 703 Pixel *ppixIn; 704 xrgb *ctable; 705#else 706 /* we'll try to cache ctable for better remote display performance */ 707 static Display *prevDisplay = NULL; 708 static XMesaColormap prevCmap = 0; 709 static int prevCmapSize = 0; 710 static XMesaColor *ctable = NULL; 711#endif 712 XMesaColor subColor; 713 int i, bestmatch; 714 double mindist; /* 3*2^16^2 exceeds long int precision. */ 715 716 (void) client; 717 718 /* First try just using XAllocColor. */ 719#ifdef XFree86Server 720 if (AllocColor(cmap, 721 &color->red, &color->green, &color->blue, 722 &color->pixel, 723 client) == Success) { 724#else 725 if (XAllocColor(dpy, cmap, color)) { 726#endif 727 *exact = 1; 728 *alloced = 1; 729 return; 730 } 731 732 /* Alloc failed, search for closest match */ 733 734 /* Retrieve color table entries. */ 735 /* XXX alloca candidate. */ 736#ifdef XFree86Server 737 ppixIn = (Pixel *) MALLOC(cmapSize * sizeof(Pixel)); 738 ctable = (xrgb *) MALLOC(cmapSize * sizeof(xrgb)); 739 for (i = 0; i < cmapSize; i++) { 740 ppixIn[i] = i; 741 } 742 QueryColors(cmap, cmapSize, ppixIn, ctable); 743#else 744 if (prevDisplay != dpy || prevCmap != cmap 745 || prevCmapSize != cmapSize || !ctable) { 746 /* free previously cached color table */ 747 if (ctable) 748 _mesa_free(ctable); 749 /* Get the color table from X */ 750 ctable = (XMesaColor *) MALLOC(cmapSize * sizeof(XMesaColor)); 751 assert(ctable); 752 for (i = 0; i < cmapSize; i++) { 753 ctable[i].pixel = i; 754 } 755 XQueryColors(dpy, cmap, ctable, cmapSize); 756 prevDisplay = dpy; 757 prevCmap = cmap; 758 prevCmapSize = cmapSize; 759 } 760#endif 761 762 /* Find best match. */ 763 bestmatch = -1; 764 mindist = 0.0; 765 for (i = 0; i < cmapSize; i++) { 766 double dr = 0.30 * ((double) color->red - (double) ctable[i].red); 767 double dg = 0.59 * ((double) color->green - (double) ctable[i].green); 768 double db = 0.11 * ((double) color->blue - (double) ctable[i].blue); 769 double dist = dr * dr + dg * dg + db * db; 770 if (bestmatch < 0 || dist < mindist) { 771 bestmatch = i; 772 mindist = dist; 773 } 774 } 775 776 /* Return result. */ 777 subColor.red = ctable[bestmatch].red; 778 subColor.green = ctable[bestmatch].green; 779 subColor.blue = ctable[bestmatch].blue; 780 /* Try to allocate the closest match color. This should only 781 * fail if the cell is read/write. Otherwise, we're incrementing 782 * the cell's reference count. 783 */ 784#ifdef XFree86Server 785 if (AllocColor(cmap, 786 &subColor.red, &subColor.green, &subColor.blue, 787 &subColor.pixel, 788 client) == Success) { 789#else 790 if (XAllocColor(dpy, cmap, &subColor)) { 791#endif 792 *alloced = 1; 793 } 794 else { 795 /* do this to work around a problem reported by Frank Ortega */ 796 subColor.pixel = (unsigned long) bestmatch; 797 subColor.red = ctable[bestmatch].red; 798 subColor.green = ctable[bestmatch].green; 799 subColor.blue = ctable[bestmatch].blue; 800 subColor.flags = DoRed | DoGreen | DoBlue; 801 *alloced = 0; 802 } 803#ifdef XFree86Server 804 _mesa_free(ppixIn); 805 _mesa_free(ctable); 806#else 807 /* don't free table, save it for next time */ 808#endif 809 810 *color = subColor; 811 *exact = 0; 812} 813 814 815 816 817/* 818 * Do setup for PF_GRAYSCALE pixel format. 819 * Note that buffer may be NULL. 820 */ 821static GLboolean setup_grayscale( int client, XMesaVisual v, 822 XMesaBuffer buffer, XMesaColormap cmap ) 823{ 824 if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) { 825 return GL_FALSE; 826 } 827 828 if (buffer) { 829 XMesaBuffer prevBuffer; 830 831 if (!cmap) { 832 return GL_FALSE; 833 } 834 835 prevBuffer = find_xmesa_buffer(v->display, cmap, buffer); 836 if (prevBuffer && 837 (buffer->xm_visual->mesa_visual.rgbMode == 838 prevBuffer->xm_visual->mesa_visual.rgbMode)) { 839 /* Copy colormap stuff from previous XMesaBuffer which uses same 840 * X colormap. Do this to avoid time spent in noFaultXAllocColor. 841 */ 842 copy_colortable_info(buffer, prevBuffer); 843 } 844 else { 845 /* Allocate 256 shades of gray */ 846 int gray; 847 int colorsfailed = 0; 848 for (gray=0;gray<256;gray++) { 849 GLint r = gamma_adjust( v->RedGamma, gray, 255 ); 850 GLint g = gamma_adjust( v->GreenGamma, gray, 255 ); 851 GLint b = gamma_adjust( v->BlueGamma, gray, 255 ); 852 int exact, alloced; 853 XMesaColor xcol; 854 xcol.red = (r << 8) | r; 855 xcol.green = (g << 8) | g; 856 xcol.blue = (b << 8) | b; 857 noFaultXAllocColor( client, v->display, 858 cmap, GET_COLORMAP_SIZE(v), 859 &xcol, &exact, &alloced ); 860 if (!exact) { 861 colorsfailed++; 862 } 863 if (alloced) { 864 assert(buffer->num_alloced<256); 865 buffer->alloced_colors[buffer->num_alloced] = xcol.pixel; 866 buffer->num_alloced++; 867 } 868 869 /*OLD 870 assert(gray < 576); 871 buffer->color_table[gray*3+0] = xcol.pixel; 872 buffer->color_table[gray*3+1] = xcol.pixel; 873 buffer->color_table[gray*3+2] = xcol.pixel; 874 assert(xcol.pixel < 65536); 875 buffer->pixel_to_r[xcol.pixel] = gray * 30 / 100; 876 buffer->pixel_to_g[xcol.pixel] = gray * 59 / 100; 877 buffer->pixel_to_b[xcol.pixel] = gray * 11 / 100; 878 */ 879 buffer->color_table[gray] = xcol.pixel; 880 assert(xcol.pixel < 65536); 881 buffer->pixel_to_r[xcol.pixel] = gray; 882 buffer->pixel_to_g[xcol.pixel] = gray; 883 buffer->pixel_to_b[xcol.pixel] = gray; 884 } 885 886 if (colorsfailed && _mesa_getenv("MESA_DEBUG")) { 887 _mesa_warning(NULL, 888 "Note: %d out of 256 needed colors do not match exactly.\n", 889 colorsfailed ); 890 } 891 } 892 } 893 894 v->dithered_pf = PF_Grayscale; 895 v->undithered_pf = PF_Grayscale; 896 return GL_TRUE; 897} 898 899 900 901/* 902 * Setup RGB rendering for a window with a PseudoColor, StaticColor, 903 * or 8-bit TrueColor visual visual. We try to allocate a palette of 225 904 * colors (5 red, 9 green, 5 blue) and dither to approximate a 24-bit RGB 905 * color. While this function was originally designed just for 8-bit 906 * visuals, it has also proven to work from 4-bit up to 16-bit visuals. 907 * Dithering code contributed by Bob Mercier. 908 */ 909static GLboolean setup_dithered_color( int client, XMesaVisual v, 910 XMesaBuffer buffer, XMesaColormap cmap ) 911{ 912 if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) { 913 return GL_FALSE; 914 } 915 916 if (buffer) { 917 XMesaBuffer prevBuffer; 918 919 if (!cmap) { 920 return GL_FALSE; 921 } 922 923 prevBuffer = find_xmesa_buffer(v->display, cmap, buffer); 924 if (prevBuffer && 925 (buffer->xm_visual->mesa_visual.rgbMode == 926 prevBuffer->xm_visual->mesa_visual.rgbMode)) { 927 /* Copy colormap stuff from previous, matching XMesaBuffer. 928 * Do this to avoid time spent in noFaultXAllocColor. 929 */ 930 copy_colortable_info(buffer, prevBuffer); 931 } 932 else { 933 /* Allocate X colors and initialize color_table[], red_table[], etc */ 934 int r, g, b, i; 935 int colorsfailed = 0; 936 for (r = 0; r < DITH_R; r++) { 937 for (g = 0; g < DITH_G; g++) { 938 for (b = 0; b < DITH_B; b++) { 939 XMesaColor xcol; 940 int exact, alloced; 941 xcol.red =gamma_adjust(v->RedGamma, r*65535/(DITH_R-1),65535); 942 xcol.green=gamma_adjust(v->GreenGamma, g*65535/(DITH_G-1),65535); 943 xcol.blue =gamma_adjust(v->BlueGamma, b*65535/(DITH_B-1),65535); 944 noFaultXAllocColor( client, v->display, 945 cmap, GET_COLORMAP_SIZE(v), 946 &xcol, &exact, &alloced ); 947 if (!exact) { 948 colorsfailed++; 949 } 950 if (alloced) { 951 assert(buffer->num_alloced<256); 952 buffer->alloced_colors[buffer->num_alloced] = xcol.pixel; 953 buffer->num_alloced++; 954 } 955 i = DITH_MIX( r, g, b ); 956 assert(i < 576); 957 buffer->color_table[i] = xcol.pixel; 958 assert(xcol.pixel < 65536); 959 buffer->pixel_to_r[xcol.pixel] = r * 255 / (DITH_R-1); 960 buffer->pixel_to_g[xcol.pixel] = g * 255 / (DITH_G-1); 961 buffer->pixel_to_b[xcol.pixel] = b * 255 / (DITH_B-1); 962 } 963 } 964 } 965 966 if (colorsfailed && _mesa_getenv("MESA_DEBUG")) { 967 _mesa_warning(NULL, 968 "Note: %d out of %d needed colors do not match exactly.\n", 969 colorsfailed, DITH_R * DITH_G * DITH_B ); 970 } 971 } 972 } 973 974 v->dithered_pf = PF_Dither; 975 v->undithered_pf = PF_Lookup; 976 return GL_TRUE; 977} 978 979 980/* 981 * Setup for Hewlett Packard Color Recovery 8-bit TrueColor mode. 982 * HPCR simulates 24-bit color fidelity with an 8-bit frame buffer. 983 * Special dithering tables have to be initialized. 984 */ 985static void setup_8bit_hpcr( XMesaVisual v ) 986{ 987 /* HP Color Recovery contributed by: Alex De Bruyn (ad@lms.be) 988 * To work properly, the atom _HP_RGB_SMOOTH_MAP_LIST must be defined 989 * on the root window AND the colormap obtainable by XGetRGBColormaps 990 * for that atom must be set on the window. (see also tkInitWindow) 991 * If that colormap is not set, the output will look stripy. 992 */ 993 994 /* Setup color tables with gamma correction */ 995 int i; 996 double g; 997 998 g = 1.0 / v->RedGamma; 999 for (i=0; i<256; i++) { 1000 GLint red = IROUND_POS(255.0 * _mesa_pow( hpcr_rgbTbl[0][i]/255.0, g )); 1001 v->hpcr_rgbTbl[0][i] = CLAMP( red, 16, 239 ); 1002 } 1003 1004 g = 1.0 / v->GreenGamma; 1005 for (i=0; i<256; i++) { 1006 GLint green = IROUND_POS(255.0 * _mesa_pow( hpcr_rgbTbl[1][i]/255.0, g )); 1007 v->hpcr_rgbTbl[1][i] = CLAMP( green, 16, 239 ); 1008 } 1009 1010 g = 1.0 / v->BlueGamma; 1011 for (i=0; i<256; i++) { 1012 GLint blue = IROUND_POS(255.0 * _mesa_pow( hpcr_rgbTbl[2][i]/255.0, g )); 1013 v->hpcr_rgbTbl[2][i] = CLAMP( blue, 32, 223 ); 1014 } 1015 v->undithered_pf = PF_HPCR; /* can't really disable dithering for now */ 1016 v->dithered_pf = PF_HPCR; 1017 1018 /* which method should I use to clear */ 1019 /* GL_FALSE: keep the ordinary method */ 1020 /* GL_TRUE : clear with dither pattern */ 1021 v->hpcr_clear_flag = _mesa_getenv("MESA_HPCR_CLEAR") ? GL_TRUE : GL_FALSE; 1022 1023 if (v->hpcr_clear_flag) { 1024 v->hpcr_clear_pixmap = XMesaCreatePixmap(v->display, 1025 DefaultRootWindow(v->display), 1026 16, 2, 8); 1027#ifndef XFree86Server 1028 v->hpcr_clear_ximage = XGetImage(v->display, v->hpcr_clear_pixmap, 1029 0, 0, 16, 2, AllPlanes, ZPixmap); 1030#endif 1031 } 1032} 1033 1034 1035/* 1036 * Setup RGB rendering for a window with a True/DirectColor visual. 1037 */ 1038static void setup_truecolor( XMesaVisual v, XMesaBuffer buffer, 1039 XMesaColormap cmap ) 1040{ 1041 unsigned long rmask, gmask, bmask; 1042 (void) buffer; 1043 (void) cmap; 1044 1045 /* Compute red multiplier (mask) and bit shift */ 1046 v->rshift = 0; 1047 rmask = GET_REDMASK(v); 1048 while ((rmask & 1)==0) { 1049 v->rshift++; 1050 rmask = rmask >> 1; 1051 } 1052 1053 /* Compute green multiplier (mask) and bit shift */ 1054 v->gshift = 0; 1055 gmask = GET_GREENMASK(v); 1056 while ((gmask & 1)==0) { 1057 v->gshift++; 1058 gmask = gmask >> 1; 1059 } 1060 1061 /* Compute blue multiplier (mask) and bit shift */ 1062 v->bshift = 0; 1063 bmask = GET_BLUEMASK(v); 1064 while ((bmask & 1)==0) { 1065 v->bshift++; 1066 bmask = bmask >> 1; 1067 } 1068 1069 /* 1070 * Compute component-to-pixel lookup tables and dithering kernel 1071 */ 1072 { 1073 static GLubyte kernel[16] = { 1074 0*16, 8*16, 2*16, 10*16, 1075 12*16, 4*16, 14*16, 6*16, 1076 3*16, 11*16, 1*16, 9*16, 1077 15*16, 7*16, 13*16, 5*16, 1078 }; 1079 GLint rBits = bitcount(rmask); 1080 GLint gBits = bitcount(gmask); 1081 GLint bBits = bitcount(bmask); 1082 GLint maxBits; 1083 GLuint i; 1084 1085 /* convert pixel components in [0,_mask] to RGB values in [0,255] */ 1086 for (i=0; i<=rmask; i++) 1087 v->PixelToR[i] = (unsigned char) ((i * 255) / rmask); 1088 for (i=0; i<=gmask; i++) 1089 v->PixelToG[i] = (unsigned char) ((i * 255) / gmask); 1090 for (i=0; i<=bmask; i++) 1091 v->PixelToB[i] = (unsigned char) ((i * 255) / bmask); 1092 1093 /* convert RGB values from [0,255] to pixel components */ 1094 1095 for (i=0;i<256;i++) { 1096 GLint r = gamma_adjust(v->RedGamma, i, 255); 1097 GLint g = gamma_adjust(v->GreenGamma, i, 255); 1098 GLint b = gamma_adjust(v->BlueGamma, i, 255); 1099 v->RtoPixel[i] = (r >> (8-rBits)) << v->rshift; 1100 v->GtoPixel[i] = (g >> (8-gBits)) << v->gshift; 1101 v->BtoPixel[i] = (b >> (8-bBits)) << v->bshift; 1102 } 1103 /* overflow protection */ 1104 for (i=256;i<512;i++) { 1105 v->RtoPixel[i] = v->RtoPixel[255]; 1106 v->GtoPixel[i] = v->GtoPixel[255]; 1107 v->BtoPixel[i] = v->BtoPixel[255]; 1108 } 1109 1110 /* setup dithering kernel */ 1111 maxBits = rBits; 1112 if (gBits > maxBits) maxBits = gBits; 1113 if (bBits > maxBits) maxBits = bBits; 1114 for (i=0;i<16;i++) { 1115 v->Kernel[i] = kernel[i] >> maxBits; 1116 } 1117 1118 v->undithered_pf = PF_Truecolor; 1119 v->dithered_pf = (GET_VISUAL_DEPTH(v)<24) ? PF_Dither_True : PF_Truecolor; 1120 } 1121 1122 /* 1123 * Now check for TrueColor visuals which we can optimize. 1124 */ 1125 if ( GET_REDMASK(v) ==0x0000ff 1126 && GET_GREENMASK(v)==0x00ff00 1127 && GET_BLUEMASK(v) ==0xff0000 1128 && CHECK_BYTE_ORDER(v) 1129 && v->BitsPerPixel==32 1130 && sizeof(GLuint)==4 1131 && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) { 1132 /* common 32 bpp config used on SGI, Sun */ 1133 v->undithered_pf = v->dithered_pf = PF_8A8B8G8R; 1134 } 1135 else if (GET_REDMASK(v) ==0xff0000 1136 && GET_GREENMASK(v)==0x00ff00 1137 && GET_BLUEMASK(v) ==0x0000ff 1138 && CHECK_BYTE_ORDER(v) 1139 && v->BitsPerPixel==32 1140 && sizeof(GLuint)==4 1141 && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) { 1142 /* common 32 bpp config used on Linux, HP, IBM */ 1143 if (GET_VISUAL_DEPTH(v)==32) 1144 v->undithered_pf = v->dithered_pf = PF_8A8R8G8B; 1145 else 1146 v->undithered_pf = v->dithered_pf = PF_8R8G8B; 1147 } 1148 else if (GET_REDMASK(v) ==0xff0000 1149 && GET_GREENMASK(v)==0x00ff00 1150 && GET_BLUEMASK(v) ==0x0000ff 1151 && CHECK_BYTE_ORDER(v) 1152 && v->BitsPerPixel==24 1153 && sizeof(GLuint)==4 1154 && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) { 1155 /* common packed 24 bpp config used on Linux */ 1156 v->undithered_pf = v->dithered_pf = PF_8R8G8B24; 1157 } 1158 else if (GET_REDMASK(v) ==0xf800 1159 && GET_GREENMASK(v)==0x07e0 1160 && GET_BLUEMASK(v) ==0x001f 1161 && CHECK_BYTE_ORDER(v) 1162 && v->BitsPerPixel==16 1163 && sizeof(GLushort)==2 1164 && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) { 1165 /* 5-6-5 color weight on common PC VGA boards */ 1166 v->undithered_pf = PF_5R6G5B; 1167 v->dithered_pf = PF_Dither_5R6G5B; 1168 } 1169 else if (GET_REDMASK(v) ==0xe0 1170 && GET_GREENMASK(v)==0x1c 1171 && GET_BLUEMASK(v) ==0x03 1172 && CHECK_FOR_HPCR(v)) { 1173 setup_8bit_hpcr( v ); 1174 } 1175} 1176 1177 1178 1179/* 1180 * Setup RGB rendering for a window with a monochrome visual. 1181 */ 1182static void setup_monochrome( XMesaVisual v, XMesaBuffer b ) 1183{ 1184 (void) b; 1185 v->dithered_pf = v->undithered_pf = PF_1Bit; 1186 /* if black=1 then we must flip pixel values */ 1187 v->bitFlip = (GET_BLACK_PIXEL(v) != 0); 1188} 1189 1190 1191 1192/* 1193 * When a context is "made current" for the first time, we can finally 1194 * finish initializing the context's visual and buffer information. 1195 * Input: v - the XMesaVisual to initialize 1196 * b - the XMesaBuffer to initialize (may be NULL) 1197 * rgb_flag - TRUE = RGBA mode, FALSE = color index mode 1198 * window - the window/pixmap we're rendering into 1199 * cmap - the colormap associated with the window/pixmap 1200 * Return: GL_TRUE=success, GL_FALSE=failure 1201 */ 1202static GLboolean initialize_visual_and_buffer( int client, 1203 XMesaVisual v, 1204 XMesaBuffer b, 1205 GLboolean rgb_flag, 1206 XMesaDrawable window, 1207 XMesaColormap cmap ) 1208{ 1209 struct xmesa_renderbuffer *front_xrb, *back_xrb; 1210#ifndef XFree86Server 1211 XGCValues gcvalues; 1212#endif 1213 1214 if (b) { 1215 assert(b->xm_visual == v); 1216 } 1217 1218 if (b) { 1219 front_xrb = b->frontxrb; 1220 back_xrb = b->backxrb; 1221 } 1222 else { 1223 front_xrb = back_xrb = NULL; 1224 } 1225 1226 /* Save true bits/pixel */ 1227 v->BitsPerPixel = bits_per_pixel(v); 1228 assert(v->BitsPerPixel > 0); 1229 1230 1231 if (rgb_flag==GL_FALSE) { 1232 /* COLOR-INDEXED WINDOW: 1233 * Even if the visual is TrueColor or DirectColor we treat it as 1234 * being color indexed. This is weird but might be useful to someone. 1235 */ 1236 v->dithered_pf = v->undithered_pf = PF_Index; 1237 v->mesa_visual.indexBits = GET_VISUAL_DEPTH(v); 1238 } 1239 else { 1240 /* RGB WINDOW: 1241 * We support RGB rendering into almost any kind of visual. 1242 */ 1243 const int xclass = v->mesa_visual.visualType; 1244 if (xclass==GLX_TRUE_COLOR || xclass==GLX_DIRECT_COLOR) { 1245 setup_truecolor( v, b, cmap ); 1246 } 1247 else if (xclass==GLX_STATIC_GRAY && GET_VISUAL_DEPTH(v)==1) { 1248 setup_monochrome( v, b ); 1249 } 1250 else if (xclass==GLX_GRAY_SCALE || xclass==GLX_STATIC_GRAY) { 1251 if (!setup_grayscale( client, v, b, cmap )) { 1252 return GL_FALSE; 1253 } 1254 } 1255 else if ((xclass==GLX_PSEUDO_COLOR || xclass==GLX_STATIC_COLOR) 1256 && GET_VISUAL_DEPTH(v)>=4 && GET_VISUAL_DEPTH(v)<=16) { 1257 if (!setup_dithered_color( client, v, b, cmap )) { 1258 return GL_FALSE; 1259 } 1260 } 1261 else { 1262 _mesa_warning(NULL, "XMesa: RGB mode rendering not supported in given visual."); 1263 return GL_FALSE; 1264 } 1265 v->mesa_visual.indexBits = 0; 1266 1267 if (_mesa_getenv("MESA_NO_DITHER")) { 1268 v->dithered_pf = v->undithered_pf; 1269 } 1270 } 1271 1272 1273 /* 1274 * If MESA_INFO env var is set print out some debugging info 1275 * which can help Brian figure out what's going on when a user 1276 * reports bugs. 1277 */ 1278 if (_mesa_getenv("MESA_INFO")) { 1279 _mesa_printf("X/Mesa visual = %p\n", (void *) v); 1280 _mesa_printf("X/Mesa dithered pf = %u\n", v->dithered_pf); 1281 _mesa_printf("X/Mesa undithered pf = %u\n", v->undithered_pf); 1282 _mesa_printf("X/Mesa level = %d\n", v->mesa_visual.level); 1283 _mesa_printf("X/Mesa depth = %d\n", GET_VISUAL_DEPTH(v)); 1284 _mesa_printf("X/Mesa bits per pixel = %d\n", v->BitsPerPixel); 1285 } 1286 1287 if (b && window) { 1288 /* Do window-specific initializations */ 1289 1290 b->frontxrb->pixmap = window; 1291 1292 /* Setup for single/double buffering */ 1293 if (v->mesa_visual.doubleBufferMode) { 1294 /* Double buffered */ 1295#ifndef XFree86Server 1296 b->shm = check_for_xshm( v->display ); 1297#endif 1298 xmesa_alloc_back_buffer(b, b->mesa_buffer.Width, b->mesa_buffer.Height); 1299 } 1300 1301 /* X11 graphics contexts */ 1302#ifdef XFree86Server 1303 b->gc = CreateScratchGC(v->display, window->depth); 1304#else 1305 b->gc = XCreateGC( v->display, window, 0, NULL ); 1306#endif 1307 XMesaSetFunction( v->display, b->gc, GXcopy ); 1308 1309 /* cleargc - for glClear() */ 1310#ifdef XFree86Server 1311 b->cleargc = CreateScratchGC(v->display, window->depth); 1312#else 1313 b->cleargc = XCreateGC( v->display, window, 0, NULL ); 1314#endif 1315 XMesaSetFunction( v->display, b->cleargc, GXcopy ); 1316 1317 /* 1318 * Don't generate Graphics Expose/NoExpose events in swapbuffers(). 1319 * Patch contributed by Michael Pichler May 15, 1995. 1320 */ 1321#ifdef XFree86Server 1322 b->swapgc = CreateScratchGC(v->display, window->depth); 1323 { 1324 CARD32 v[1]; 1325 v[0] = FALSE; 1326 dixChangeGC(NullClient, b->swapgc, GCGraphicsExposures, v, NULL); 1327 } 1328#else 1329 gcvalues.graphics_exposures = False; 1330 b->swapgc = XCreateGC( v->display, window, 1331 GCGraphicsExposures, &gcvalues); 1332#endif 1333 XMesaSetFunction( v->display, b->swapgc, GXcopy ); 1334 /* 1335 * Set fill style and tile pixmap once for all for HPCR stuff 1336 * (instead of doing it each time in clear_color_HPCR_pixmap()) 1337 * Initialize whole stuff 1338 * Patch contributed by Jacques Leroy March 8, 1998. 1339 */ 1340 if (v->hpcr_clear_flag && back_xrb->pixmap) { 1341 int i; 1342 for (i=0; i<16; i++) 1343 { 1344 XMesaPutPixel(v->hpcr_clear_ximage, i, 0, 0); 1345 XMesaPutPixel(v->hpcr_clear_ximage, i, 1, 0); 1346 } 1347 XMesaPutImage(b->display, (XMesaDrawable)v->hpcr_clear_pixmap, 1348 b->cleargc, v->hpcr_clear_ximage, 0, 0, 0, 0, 16, 2); 1349 XMesaSetFillStyle( v->display, b->cleargc, FillTiled); 1350 XMesaSetTile( v->display, b->cleargc, v->hpcr_clear_pixmap ); 1351 } 1352 1353 /* Initialize the row buffer XImage for use in write_color_span() */ 1354#ifdef XFree86Server 1355 b->rowimage = XMesaCreateImage(GET_VISUAL_DEPTH(v), MAX_WIDTH, 1, 1356 (char *)MALLOC(MAX_WIDTH*4)); 1357#else 1358 b->rowimage = XCreateImage( v->display, 1359 v->visinfo->visual, 1360 v->visinfo->depth, 1361 ZPixmap, 0, /*format, offset*/ 1362 (char*) MALLOC(MAX_WIDTH*4), /*data*/ 1363 MAX_WIDTH, 1, /*width, height*/ 1364 32, /*bitmap_pad*/ 1365 0 /*bytes_per_line*/ ); 1366#endif 1367 if (!b->rowimage) 1368 return GL_FALSE; 1369 } 1370 1371 return GL_TRUE; 1372} 1373 1374 1375 1376/* 1377 * Convert an RGBA color to a pixel value. 1378 */ 1379unsigned long 1380xmesa_color_to_pixel(GLcontext *ctx, 1381 GLubyte r, GLubyte g, GLubyte b, GLubyte a, 1382 GLuint pixelFormat) 1383{ 1384 XMesaContext xmesa = XMESA_CONTEXT(ctx); 1385 switch (pixelFormat) { 1386 case PF_Index: 1387 return 0; 1388 case PF_Truecolor: 1389 { 1390 unsigned long p; 1391 PACK_TRUECOLOR( p, r, g, b ); 1392 return p; 1393 } 1394 case PF_8A8B8G8R: 1395 return PACK_8A8B8G8R( r, g, b, a ); 1396 case PF_8A8R8G8B: 1397 return PACK_8A8R8G8B( r, g, b, a ); 1398 case PF_8R8G8B: 1399 /* fall through */ 1400 case PF_8R8G8B24: 1401 return PACK_8R8G8B( r, g, b ); 1402 case PF_5R6G5B: 1403 return PACK_5R6G5B( r, g, b ); 1404 case PF_Dither: 1405 { 1406 DITHER_SETUP; 1407 return DITHER( 1, 0, r, g, b ); 1408 } 1409 case PF_1Bit: 1410 /* 382 = (3*255)/2 */ 1411 return ((r+g+b) > 382) ^ xmesa->xm_visual->bitFlip; 1412 case PF_HPCR: 1413 return DITHER_HPCR(1, 1, r, g, b); 1414 case PF_Lookup: 1415 { 1416 LOOKUP_SETUP; 1417 return LOOKUP( r, g, b ); 1418 } 1419 case PF_Grayscale: 1420 return GRAY_RGB( r, g, b ); 1421 case PF_Dither_True: 1422 /* fall through */ 1423 case PF_Dither_5R6G5B: 1424 { 1425 unsigned long p; 1426 PACK_TRUEDITHER(p, 1, 0, r, g, b); 1427 return p; 1428 } 1429 default: 1430 _mesa_problem(ctx, "Bad pixel format in xmesa_color_to_pixel"); 1431 } 1432 return 0; 1433} 1434 1435 1436#define NUM_VISUAL_TYPES 6 1437 1438/** 1439 * Convert an X visual type to a GLX visual type. 1440 * 1441 * \param visualType X visual type (i.e., \c TrueColor, \c StaticGray, etc.) 1442 * to be converted. 1443 * \return If \c visualType is a valid X visual type, a GLX visual type will 1444 * be returned. Otherwise \c GLX_NONE will be returned. 1445 * 1446 * \note 1447 * This code was lifted directly from lib/GL/glx/glcontextmodes.c in the 1448 * DRI CVS tree. 1449 */ 1450static GLint 1451xmesa_convert_from_x_visual_type( int visualType ) 1452{ 1453 static const int glx_visual_types[ NUM_VISUAL_TYPES ] = { 1454 GLX_STATIC_GRAY, GLX_GRAY_SCALE, 1455 GLX_STATIC_COLOR, GLX_PSEUDO_COLOR, 1456 GLX_TRUE_COLOR, GLX_DIRECT_COLOR 1457 }; 1458 1459 return ( (unsigned) visualType < NUM_VISUAL_TYPES ) 1460 ? glx_visual_types[ visualType ] : GLX_NONE; 1461} 1462 1463 1464/**********************************************************************/ 1465/***** Public Functions *****/ 1466/**********************************************************************/ 1467 1468 1469/* 1470 * Create a new X/Mesa visual. 1471 * Input: display - X11 display 1472 * visinfo - an XVisualInfo pointer 1473 * rgb_flag - GL_TRUE = RGB mode, 1474 * GL_FALSE = color index mode 1475 * alpha_flag - alpha buffer requested? 1476 * db_flag - GL_TRUE = double-buffered, 1477 * GL_FALSE = single buffered 1478 * stereo_flag - stereo visual? 1479 * ximage_flag - GL_TRUE = use an XImage for back buffer, 1480 * GL_FALSE = use an off-screen pixmap for back buffer 1481 * depth_size - requested bits/depth values, or zero 1482 * stencil_size - requested bits/stencil values, or zero 1483 * accum_red_size - requested bits/red accum values, or zero 1484 * accum_green_size - requested bits/green accum values, or zero 1485 * accum_blue_size - requested bits/blue accum values, or zero 1486 * accum_alpha_size - requested bits/alpha accum values, or zero 1487 * num_samples - number of samples/pixel if multisampling, or zero 1488 * level - visual level, usually 0 1489 * visualCaveat - ala the GLX extension, usually GLX_NONE 1490 * Return; a new XMesaVisual or 0 if error. 1491 */ 1492XMesaVisual XMesaCreateVisual( XMesaDisplay *display, 1493 XMesaVisualInfo visinfo, 1494 GLboolean rgb_flag, 1495 GLboolean alpha_flag, 1496 GLboolean db_flag, 1497 GLboolean stereo_flag, 1498 GLboolean ximage_flag, 1499 GLint depth_size, 1500 GLint stencil_size, 1501 GLint accum_red_size, 1502 GLint accum_green_size, 1503 GLint accum_blue_size, 1504 GLint accum_alpha_size, 1505 GLint num_samples, 1506 GLint level, 1507 GLint visualCaveat ) 1508{ 1509 char *gamma; 1510 XMesaVisual v; 1511 GLint red_bits, green_bits, blue_bits, alpha_bits; 1512 1513 /* For debugging only */ 1514 if (_mesa_getenv("MESA_XSYNC")) { 1515 /* This makes debugging X easier. 1516 * In your debugger, set a breakpoint on _XError to stop when an 1517 * X protocol error is generated. 1518 */ 1519#ifdef XFree86Server 1520 /* NOT_NEEDED */ 1521#else 1522 XSynchronize( display, 1 ); 1523#endif 1524 } 1525 1526 v = (XMesaVisual) CALLOC_STRUCT(xmesa_visual); 1527 if (!v) { 1528 return NULL; 1529 } 1530 1531 /* 1532 * In the X server, NULL is passed in for the display. It will have 1533 * to be set before using this visual. See XMesaSetVisualDisplay() 1534 * below. 1535 */ 1536 v->display = display; 1537 1538 /* Save a copy of the XVisualInfo struct because the user may X_mesa_free() 1539 * the struct but we may need some of the information contained in it 1540 * at a later time. 1541 */ 1542#ifndef XFree86Server 1543 v->visinfo = (XVisualInfo *) MALLOC(sizeof(*visinfo)); 1544 if(!v->visinfo) { 1545 _mesa_free(v); 1546 return NULL; 1547 } 1548 MEMCPY(v->visinfo, visinfo, sizeof(*visinfo)); 1549#endif 1550 1551 /* check for MESA_GAMMA environment variable */ 1552 gamma = _mesa_getenv("MESA_GAMMA"); 1553 if (gamma) { 1554 v->RedGamma = v->GreenGamma = v->BlueGamma = 0.0; 1555 sscanf( gamma, "%f %f %f", &v->RedGamma, &v->GreenGamma, &v->BlueGamma ); 1556 if (v->RedGamma<=0.0) v->RedGamma = 1.0; 1557 if (v->GreenGamma<=0.0) v->GreenGamma = v->RedGamma; 1558 if (v->BlueGamma<=0.0) v->BlueGamma = v->RedGamma; 1559 } 1560 else { 1561 v->RedGamma = v->GreenGamma = v->BlueGamma = 1.0; 1562 } 1563 1564 v->ximage_flag = ximage_flag; 1565 1566#ifdef XFree86Server 1567 /* We could calculate these values by ourselves. nplanes is either the sum 1568 * of the red, green, and blue bits or the number index bits. 1569 * ColormapEntries is either (1U << index_bits) or 1570 * (1U << max(redBits, greenBits, blueBits)). 1571 */ 1572 v->nplanes = visinfo->nplanes; 1573 v->ColormapEntries = visinfo->ColormapEntries; 1574 1575 v->mesa_visual.redMask = visinfo->redMask; 1576 v->mesa_visual.greenMask = visinfo->greenMask; 1577 v->mesa_visual.blueMask = visinfo->blueMask; 1578 v->mesa_visual.visualID = visinfo->vid; 1579 v->mesa_visual.screen = 0; /* FIXME: What should be done here? */ 1580#else 1581 v->mesa_visual.redMask = visinfo->red_mask; 1582 v->mesa_visual.greenMask = visinfo->green_mask; 1583 v->mesa_visual.blueMask = visinfo->blue_mask; 1584 v->mesa_visual.visualID = visinfo->visualid; 1585 v->mesa_visual.screen = visinfo->screen; 1586#endif 1587 1588#if defined(XFree86Server) || !(defined(__cplusplus) || defined(c_plusplus)) 1589 v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->class); 1590#else 1591 v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->c_class); 1592#endif 1593 1594 v->mesa_visual.visualRating = visualCaveat; 1595 1596 (void) initialize_visual_and_buffer( 0, v, NULL, rgb_flag, 0, 0 ); 1597 1598 { 1599 const int xclass = v->mesa_visual.visualType; 1600 if (xclass==GLX_TRUE_COLOR || xclass==GLX_DIRECT_COLOR) { 1601 red_bits = bitcount(GET_REDMASK(v)); 1602 green_bits = bitcount(GET_GREENMASK(v)); 1603 blue_bits = bitcount(GET_BLUEMASK(v)); 1604 alpha_bits = 0; 1605 } 1606 else { 1607 /* this is an approximation */ 1608 int depth; 1609 depth = GET_VISUAL_DEPTH(v); 1610 red_bits = depth / 3; 1611 depth -= red_bits; 1612 green_bits = depth / 2; 1613 depth -= green_bits; 1614 blue_bits = depth; 1615 alpha_bits = 0; 1616 assert( red_bits + green_bits + blue_bits == GET_VISUAL_DEPTH(v) ); 1617 } 1618 } 1619 1620 if (alpha_flag && alpha_bits == 0) 1621 alpha_bits = 8; 1622 1623 _mesa_initialize_visual( &v->mesa_visual, 1624 rgb_flag, db_flag, stereo_flag, 1625 red_bits, green_bits, 1626 blue_bits, alpha_bits, 1627 v->mesa_visual.indexBits, 1628 depth_size, 1629 stencil_size, 1630 accum_red_size, accum_green_size, 1631 accum_blue_size, accum_alpha_size, 1632 0 ); 1633 1634 /* XXX minor hack */ 1635 v->mesa_visual.level = level; 1636 return v; 1637} 1638 1639 1640void XMesaSetVisualDisplay( XMesaDisplay *dpy, XMesaVisual v ) 1641{ 1642 v->display = dpy; 1643} 1644 1645 1646void XMesaDestroyVisual( XMesaVisual v ) 1647{ 1648#ifndef XFree86Server 1649 _mesa_free(v->visinfo); 1650#endif 1651 _mesa_free(v); 1652} 1653 1654 1655 1656/** 1657 * Create a new XMesaContext. 1658 * \param v the XMesaVisual 1659 * \param share_list another XMesaContext with which to share display 1660 * lists or NULL if no sharing is wanted. 1661 * \return an XMesaContext or NULL if error. 1662 */ 1663XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) 1664{ 1665 static GLboolean firstTime = GL_TRUE; 1666 XMesaContext c; 1667 GLcontext *mesaCtx; 1668 struct dd_function_table functions; 1669 TNLcontext *tnl; 1670 1671 if (firstTime) { 1672 _glthread_INIT_MUTEX(_xmesa_lock); 1673 firstTime = GL_FALSE; 1674 } 1675 1676 /* Note: the XMesaContext contains a Mesa GLcontext struct (inheritance) */ 1677 c = (XMesaContext) CALLOC_STRUCT(xmesa_context); 1678 if (!c) 1679 return NULL; 1680 1681 mesaCtx = &(c->mesa); 1682 1683 /* initialize with default driver functions, then plug in XMesa funcs */ 1684 _mesa_init_driver_functions(&functions); 1685 xmesa_init_driver_functions(v, &functions); 1686 if (!_mesa_initialize_context(mesaCtx, &v->mesa_visual, 1687 share_list ? &(share_list->mesa) : (GLcontext *) NULL, 1688 &functions, (void *) c)) { 1689 _mesa_free(c); 1690 return NULL; 1691 } 1692 1693 _mesa_enable_sw_extensions(mesaCtx); 1694 _mesa_enable_1_3_extensions(mesaCtx); 1695 _mesa_enable_1_4_extensions(mesaCtx); 1696 _mesa_enable_1_5_extensions(mesaCtx); 1697 _mesa_enable_2_0_extensions(mesaCtx); 1698#if SWTC 1699 if (c->Mesa_DXTn) { 1700 _mesa_enable_extension(c, "GL_EXT_texture_compression_s3tc"); 1701 _mesa_enable_extension(c, "GL_S3_s3tc"); 1702 } 1703 _mesa_enable_extension(c, "GL_3DFX_texture_compression_FXT1"); 1704#endif 1705 1706 /* finish up xmesa context initializations */ 1707 c->swapbytes = CHECK_BYTE_ORDER(v) ? GL_FALSE : GL_TRUE; 1708 c->xm_visual = v; 1709 c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */ 1710 c->display = v->display; 1711 c->pixelformat = v->dithered_pf; /* Dithering is enabled by default */ 1712 1713 /* Initialize the software rasterizer and helper modules. 1714 */ 1715 if (!_swrast_CreateContext( mesaCtx ) || 1716 !_ac_CreateContext( mesaCtx ) || 1717 !_tnl_CreateContext( mesaCtx ) || 1718 !_swsetup_CreateContext( mesaCtx )) { 1719 _mesa_free_context_data(&c->mesa); 1720 _mesa_free(c); 1721 return NULL; 1722 } 1723 1724 /* tnl setup */ 1725 tnl = TNL_CONTEXT(mesaCtx); 1726 tnl->Driver.RunPipeline = _tnl_run_pipeline; 1727 /* swrast setup */ 1728 xmesa_register_swrast_functions( mesaCtx ); 1729 _swsetup_Wakeup(mesaCtx); 1730 1731 return c; 1732} 1733 1734 1735 1736void XMesaDestroyContext( XMesaContext c ) 1737{ 1738 GLcontext *mesaCtx = &c->mesa; 1739#ifdef FX 1740 XMesaBuffer xmbuf = XMESA_BUFFER(mesaCtx->DrawBuffer); 1741 1742 if (xmbuf && xmbuf->FXctx) 1743 fxMesaDestroyContext(xmbuf->FXctx); 1744#endif 1745 _swsetup_DestroyContext( mesaCtx ); 1746 _swrast_DestroyContext( mesaCtx ); 1747 _tnl_DestroyContext( mesaCtx ); 1748 _ac_DestroyContext( mesaCtx ); 1749 _mesa_free_context_data( mesaCtx ); 1750 _mesa_free( c ); 1751} 1752 1753 1754 1755/* 1756 * XXX this isn't a public function! It's a hack for the 3Dfx driver. 1757 * Create a new XMesaBuffer from an X window. 1758 * Input: v - the XMesaVisual 1759 * w - the window 1760 * c - the context 1761 * Return: new XMesaBuffer or NULL if error 1762 */ 1763XMesaBuffer 1764XMesaCreateWindowBuffer2(XMesaVisual v, XMesaWindow w, XMesaContext c) 1765{ 1766#ifndef XFree86Server 1767 XWindowAttributes attr; 1768#endif 1769#ifdef FX 1770 char *fxEnvVar; 1771#endif 1772 int client = 0; 1773 XMesaBuffer b; 1774 XMesaColormap cmap; 1775 1776 assert(v); 1777 (void) c; 1778 1779 /* Check that window depth matches visual depth */ 1780#ifdef XFree86Server 1781 client = CLIENT_ID(((XMesaDrawable)w)->id); 1782 1783 if (GET_VISUAL_DEPTH(v) != ((XMesaDrawable)w)->depth) { 1784 _mesa_warning(NULL, "XMesaCreateWindowBuffer: depth mismatch between visual (%d) and window (%d)!\n", 1785 GET_VISUAL_DEPTH(v), ((XMesaDrawable) w)->depth); 1786 return NULL; 1787 } 1788#else 1789 XGetWindowAttributes( v->display, w, &attr ); 1790 1791 if (GET_VISUAL_DEPTH(v) != attr.depth) { 1792 _mesa_warning(NULL, "XMesaCreateWindowBuffer: depth mismatch between visual (%d) and window (%d)!\n", 1793 GET_VISUAL_DEPTH(v), attr.depth); 1794 return NULL; 1795 } 1796#endif 1797 1798 /* Find colormap */ 1799#ifdef XFree86Server 1800 cmap = (ColormapPtr)LookupIDByType(wColormap(w), RT_COLORMAP); 1801#else 1802 if (attr.colormap) { 1803 cmap = attr.colormap; 1804 } 1805 else { 1806 _mesa_warning(NULL, "Window %u has no colormap!\n", (unsigned int) w); 1807 /* this is weird, a window w/out a colormap!? */ 1808 /* OK, let's just allocate a new one and hope for the best */ 1809 cmap = XCreateColormap(v->display, w, attr.visual, AllocNone); 1810 } 1811#endif 1812 1813 b = alloc_xmesa_buffer(v, WINDOW, cmap); 1814 if (!b) { 1815 return NULL; 1816 } 1817 1818 if (!initialize_visual_and_buffer( client, v, b, v->mesa_visual.rgbMode, 1819 (XMesaDrawable)w, cmap )) { 1820 free_xmesa_buffer(client, b); 1821 return NULL; 1822 } 1823 1824#ifdef FX 1825 fxEnvVar = _mesa_getenv("MESA_GLX_FX"); 1826 if (fxEnvVar) { 1827 if (fxEnvVar[0]!='d') { 1828 int attribs[100]; 1829 int numAttribs = 0; 1830 int hw; 1831 if (v->mesa_visual.depthBits > 0) { 1832 attribs[numAttribs++] = FXMESA_DEPTH_SIZE; 1833 attribs[numAttribs++] = v->mesa_visual.depthBits; 1834 } 1835 if (v->mesa_visual.doubleBufferMode) { 1836 attribs[numAttribs++] = FXMESA_DOUBLEBUFFER; 1837 } 1838 if (v->mesa_visual.accumRedBits > 0) { 1839 attribs[numAttribs++] = FXMESA_ACCUM_SIZE; 1840 attribs[numAttribs++] = v->mesa_visual.accumRedBits; 1841 } 1842 if (v->mesa_visual.stencilBits > 0) { 1843 attribs[numAttribs++] = FXMESA_STENCIL_SIZE; 1844 attribs[numAttribs++] = v->mesa_visual.stencilBits; 1845 } 1846 if (v->mesa_visual.alphaBits > 0) { 1847 attribs[numAttribs++] = FXMESA_ALPHA_SIZE; 1848 attribs[numAttribs++] = v->mesa_visual.alphaBits; 1849 } 1850 if (1) { 1851 attribs[numAttribs++] = FXMESA_SHARE_CONTEXT; 1852 attribs[numAttribs++] = (int) &(c->mesa); 1853 } 1854 attribs[numAttribs++] = FXMESA_NONE; 1855 1856 /* [dBorca] we should take an envvar for `fxMesaSelectCurrentBoard'!!! */ 1857 hw = fxMesaSelectCurrentBoard(0); 1858 1859 /* if these fail, there's a new bug somewhere */ 1860 ASSERT(b->mesa_buffer.Width > 0); 1861 ASSERT(b->mesa_buffer.Height > 0); 1862 1863 if ((hw == GR_SSTTYPE_VOODOO) || (hw == GR_SSTTYPE_Voodoo2)) { 1864 b->FXctx = fxMesaCreateBestContext(0, b->mesa_buffer.Width, 1865 b->mesa_buffer.Height, attribs); 1866 if ((v->undithered_pf!=PF_Index) && (b->backxrb->ximage)) { 1867 b->FXisHackUsable = b->FXctx ? GL_TRUE : GL_FALSE; 1868 if (b->FXctx && (fxEnvVar[0]=='w' || fxEnvVar[0]=='W')) { 1869 b->FXwindowHack = GL_TRUE; 1870 FX_grSstControl(GR_CONTROL_DEACTIVATE); 1871 } 1872 else { 1873 b->FXwindowHack = GL_FALSE; 1874 } 1875 } 1876 } 1877 else { 1878 if (fxEnvVar[0]=='w' || fxEnvVar[0]=='W') 1879 b->FXctx = fxMesaCreateContext(w, GR_RESOLUTION_NONE, 1880 GR_REFRESH_75Hz, attribs); 1881 else 1882 b->FXctx = fxMesaCreateBestContext(0, b->mesa_buffer.Width, 1883 b->mesa_buffer.Height, attribs); 1884 b->FXisHackUsable = GL_FALSE; 1885 b->FXwindowHack = GL_FALSE; 1886 } 1887 /* 1888 fprintf(stderr, 1889 "voodoo %d, wid %d height %d hack: usable %d active %d\n", 1890 hw, b->mesa_buffer.Width, b->mesa_buffer.Height, 1891 b->FXisHackUsable, b->FXwindowHack); 1892 */ 1893 } 1894 } 1895 else { 1896 _mesa_warning(NULL, "WARNING: This Mesa Library includes the Glide driver but\n"); 1897 _mesa_warning(NULL, " you have not defined the MESA_GLX_FX env. var.\n"); 1898 _mesa_warning(NULL, " (check the README.3DFX file for more information).\n\n"); 1899 _mesa_warning(NULL, " you can disable this message with a 'export MESA_GLX_FX=disable'.\n"); 1900 } 1901#endif 1902 1903 return b; 1904} 1905 1906 1907XMesaBuffer 1908XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w) 1909{ 1910 return XMesaCreateWindowBuffer2( v, w, NULL ); 1911} 1912 1913 1914/** 1915 * Create a new XMesaBuffer from an X pixmap. 1916 * 1917 * \param v the XMesaVisual 1918 * \param p the pixmap 1919 * \param cmap the colormap, may be 0 if using a \c GLX_TRUE_COLOR or 1920 * \c GLX_DIRECT_COLOR visual for the pixmap 1921 * \returns new XMesaBuffer or NULL if error 1922 */ 1923XMesaBuffer 1924XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p, XMesaColormap cmap) 1925{ 1926 int client = 0; 1927 XMesaBuffer b; 1928 1929 assert(v); 1930 1931 b = alloc_xmesa_buffer(v, PIXMAP, cmap); 1932 if (!b) { 1933 return NULL; 1934 } 1935 1936#ifdef XFree86Server 1937 client = CLIENT_ID(((XMesaDrawable)p)->id); 1938#endif 1939 1940 if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode, 1941 (XMesaDrawable)p, cmap)) { 1942 free_xmesa_buffer(client, b); 1943 return NULL; 1944 } 1945 1946 return b; 1947} 1948 1949 1950 1951XMesaBuffer 1952XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap, 1953 unsigned int width, unsigned int height) 1954{ 1955#ifdef XFree86Server 1956 return 0; 1957#else 1958 int client = 0; 1959 XMesaWindow root; 1960 XMesaDrawable drawable; /* X Pixmap Drawable */ 1961 XMesaBuffer b; 1962 1963 b = alloc_xmesa_buffer(v, PBUFFER, cmap); 1964 if (!b) { 1965 return NULL; 1966 } 1967 1968 /* allocate pixmap for front buffer */ 1969 root = RootWindow( v->display, v->visinfo->screen ); 1970 drawable = XCreatePixmap( v->display, root, width, height, v->visinfo->depth ); 1971 1972 if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode, 1973 drawable, cmap)) { 1974 free_xmesa_buffer(client, b); 1975 return NULL; 1976 } 1977 1978 return b; 1979#endif 1980} 1981 1982 1983 1984/* 1985 * Deallocate an XMesaBuffer structure and all related info. 1986 */ 1987void XMesaDestroyBuffer( XMesaBuffer b ) 1988{ 1989 int client = 0; 1990 1991#ifdef XFree86Server 1992 if (b->frontxrb->pixmap) 1993 client = CLIENT_ID(b->frontxrb->pixmap->id); 1994#endif 1995 1996 if (b->gc) XMesaFreeGC( b->xm_visual->display, b->gc ); 1997 if (b->cleargc) XMesaFreeGC( b->xm_visual->display, b->cleargc ); 1998 if (b->swapgc) XMesaFreeGC( b->xm_visual->display, b->swapgc ); 1999 2000 if (b->xm_visual->mesa_visual.doubleBufferMode) 2001 { 2002 if (b->backxrb->ximage) { 2003#if defined(USE_XSHM) && !defined(XFree86Server) 2004 if (b->shm) { 2005 XShmDetach( b->xm_visual->display, &b->shminfo ); 2006 XDestroyImage( b->backxrb->ximage ); 2007 shmdt( b->shminfo.shmaddr ); 2008 } 2009 else 2010#endif 2011 XMesaDestroyImage( b->backxrb->ximage ); 2012 } 2013 if (b->backxrb->pixmap) { 2014 XMesaFreePixmap( b->xm_visual->display, b->backxrb->pixmap ); 2015 if (b->xm_visual->hpcr_clear_flag) { 2016 XMesaFreePixmap( b->xm_visual->display, 2017 b->xm_visual->hpcr_clear_pixmap ); 2018 XMesaDestroyImage( b->xm_visual->hpcr_clear_ximage ); 2019 } 2020 } 2021 } 2022 if (b->rowimage) { 2023 _mesa_free( b->rowimage->data ); 2024 b->rowimage->data = NULL; 2025 XMesaDestroyImage( b->rowimage ); 2026 } 2027 2028 free_xmesa_buffer(client, b); 2029} 2030 2031 2032 2033/* 2034 * Bind buffer b to context c and make c the current rendering context. 2035 */ 2036GLboolean XMesaMakeCurrent( XMesaContext c, XMesaBuffer b ) 2037{ 2038 return XMesaMakeCurrent2( c, b, b ); 2039} 2040 2041 2042/* 2043 * Bind buffer b to context c and make c the current rendering context. 2044 */ 2045GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer, 2046 XMesaBuffer readBuffer ) 2047{ 2048 if (c) { 2049 if (!drawBuffer || !readBuffer) 2050 return GL_FALSE; /* must specify buffers! */ 2051 2052#ifdef FX 2053 if (drawBuffer->FXctx) { 2054 fxMesaMakeCurrent(drawBuffer->FXctx); 2055 2056 c->xm_buffer = drawBuffer; 2057 2058 return GL_TRUE; 2059 } 2060#endif 2061 if (&(c->mesa) == _mesa_get_current_context() 2062 && c->mesa.DrawBuffer == &drawBuffer->mesa_buffer 2063 && c->mesa.ReadBuffer == &readBuffer->mesa_buffer 2064 && ((XMesaBuffer) c->mesa.DrawBuffer)->wasCurrent) { 2065 /* same context and buffer, do nothing */ 2066 return GL_TRUE; 2067 } 2068 2069 c->xm_buffer = drawBuffer; 2070 2071 _mesa_make_current(&(c->mesa), 2072 &drawBuffer->mesa_buffer, 2073 &readBuffer->mesa_buffer); 2074 2075 if (c->xm_visual->mesa_visual.rgbMode) { 2076 /* 2077 * Must recompute and set these pixel values because colormap 2078 * can be different for different windows. 2079 */ 2080 c->clearpixel = xmesa_color_to_pixel( &c->mesa, 2081 c->clearcolor[0], 2082 c->clearcolor[1], 2083 c->clearcolor[2], 2084 c->clearcolor[3], 2085 c->xm_visual->undithered_pf); 2086 XMesaSetForeground(c->display, drawBuffer->cleargc, c->clearpixel); 2087 } 2088 2089 /* Solution to Stephane Rehel's problem with glXReleaseBuffersMESA(): */ 2090 drawBuffer->wasCurrent = GL_TRUE; 2091 } 2092 else { 2093 /* Detach */ 2094 _mesa_make_current( NULL, NULL, NULL ); 2095 } 2096 return GL_TRUE; 2097} 2098 2099 2100/* 2101 * Unbind the context c from its buffer. 2102 */ 2103GLboolean XMesaUnbindContext( XMesaContext c ) 2104{ 2105 /* A no-op for XFree86 integration purposes */ 2106 return GL_TRUE; 2107} 2108 2109 2110XMesaContext XMesaGetCurrentContext( void ) 2111{ 2112 GET_CURRENT_CONTEXT(ctx); 2113 if (ctx) { 2114 XMesaContext xmesa = XMESA_CONTEXT(ctx); 2115 return xmesa; 2116 } 2117 else { 2118 return 0; 2119 } 2120} 2121 2122 2123XMesaBuffer XMesaGetCurrentBuffer( void ) 2124{ 2125 GET_CURRENT_CONTEXT(ctx); 2126 if (ctx) { 2127 XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); 2128 return xmbuf; 2129 } 2130 else { 2131 return 0; 2132 } 2133} 2134 2135 2136/* New in Mesa 3.1 */ 2137XMesaBuffer XMesaGetCurrentReadBuffer( void ) 2138{ 2139 GET_CURRENT_CONTEXT(ctx); 2140 if (ctx) { 2141 return (XMesaBuffer) (ctx->ReadBuffer); 2142 } 2143 else { 2144 return 0; 2145 } 2146} 2147 2148 2149GLboolean XMesaForceCurrent(XMesaContext c) 2150{ 2151 if (c) { 2152 if (&(c->mesa) != _mesa_get_current_context()) { 2153 _mesa_make_current(&c->mesa, c->mesa.DrawBuffer, c->mesa.ReadBuffer); 2154 } 2155 } 2156 else { 2157 _mesa_make_current(NULL, NULL, NULL); 2158 } 2159 return GL_TRUE; 2160} 2161 2162 2163GLboolean XMesaLoseCurrent(XMesaContext c) 2164{ 2165 (void) c; 2166 _mesa_make_current(NULL, NULL, NULL); 2167 return GL_TRUE; 2168} 2169 2170 2171/* 2172 * Switch 3Dfx support hack between window and full-screen mode. 2173 */ 2174GLboolean XMesaSetFXmode( GLint mode ) 2175{ 2176#ifdef FX 2177 const char *fx = _mesa_getenv("MESA_GLX_FX"); 2178 if (fx && fx[0] != 'd') { 2179 GET_CURRENT_CONTEXT(ctx); 2180 GrHwConfiguration hw; 2181 if (!FX_grSstQueryHardware(&hw)) { 2182 /*fprintf(stderr, "!grSstQueryHardware\n");*/ 2183 return GL_FALSE; 2184 } 2185 if (hw.num_sst < 1) { 2186 /*fprintf(stderr, "hw.num_sst < 1\n");*/ 2187 return GL_FALSE; 2188 } 2189 if (ctx) { 2190 /* [dBorca] Hack alert: 2191 * oh, this is sooo wrong: ctx above is 2192 * really an fxMesaContext, not an XMesaContext 2193 */ 2194 XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); 2195 if (mode == XMESA_FX_WINDOW) { 2196 if (xmbuf->FXisHackUsable) { 2197 FX_grSstControl(GR_CONTROL_DEACTIVATE); 2198 xmbuf->FXwindowHack = GL_TRUE; 2199 return GL_TRUE; 2200 } 2201 } 2202 else if (mode == XMESA_FX_FULLSCREEN) { 2203 FX_grSstControl(GR_CONTROL_ACTIVATE); 2204 xmbuf->FXwindowHack = GL_FALSE; 2205 return GL_TRUE; 2206 } 2207 else { 2208 /* Error: Bad mode value */ 2209 } 2210 } 2211 } 2212 /*fprintf(stderr, "fallthrough\n");*/ 2213#else 2214 (void) mode; 2215#endif 2216 return GL_FALSE; 2217} 2218 2219 2220 2221#ifdef FX 2222/* 2223 * Read image from VooDoo frame buffer into X/Mesa's back XImage. 2224 */ 2225static void FXgetImage( XMesaBuffer b ) 2226{ 2227 GET_CURRENT_CONTEXT(ctx); 2228 static unsigned short pixbuf[MAX_WIDTH]; 2229 GLuint x, y; 2230 int xpos, ypos; 2231 XMesaWindow root; 2232 unsigned int bw, depth, width, height; 2233 XMesaContext xmesa = XMESA_CONTEXT(ctx); 2234 2235#ifdef XFree86Server 2236 x = b->frontxrb->pixmap->x; 2237 y = b->frontxrb->pixmap->y; 2238 width = b->frontxrb->pixmap->width; 2239 height = b->frontxrb->pixmap->height; 2240 depth = b->frontxrb->pixmap->depth; 2241#else 2242 XGetGeometry( b->xm_visual->display, b->frontxrb->pixmap, 2243 &root, &xpos, &ypos, &width, &height, &bw, &depth); 2244#endif 2245 if (b->mesa_buffer.Width != width || b->mesa_buffer.Height != height) { 2246 b->mesa_buffer.Width = MIN2((int)width, b->FXctx->width); 2247 b->mesa_buffer.Height = MIN2((int)height, b->FXctx->height); 2248 if (b->mesa_buffer.Width & 1) 2249 b->mesa_buffer.Width--; /* prevent odd width */ 2250 xmesa_alloc_back_buffer(b, b->mesa_buffer.Width, b->mesa_buffer.Height); 2251 } 2252 2253 /* [dBorca] we're always in the right GR_COLORFORMAT... aren't we? */ 2254 /* grLfbWriteColorFormat(GR_COLORFORMAT_ARGB); */ 2255 if (b->xm_visual->undithered_pf==PF_5R6G5B) { 2256 /* Special case: 16bpp RGB */ 2257 grLfbReadRegion( GR_BUFFER_FRONTBUFFER, /* src buffer */ 2258 0, b->FXctx->height - b->mesa_buffer.Height, /*pos*/ 2259 b->mesa_buffer.Width, b->mesa_buffer.Height, /* size */ 2260 b->mesa_buffer.Width * sizeof(GLushort), /* stride */ 2261 b->backxrb->ximage->data); /* dest buffer */ 2262 } 2263 else if (b->xm_visual->dithered_pf==PF_Dither 2264 && GET_VISUAL_DEPTH(b->xm_visual)==8) { 2265 /* Special case: 8bpp RGB */ 2266 for (y=0;y<b->mesa_buffer.Height;y++) { 2267 GLubyte *ptr = (GLubyte*) b->backxrb->ximage->data 2268 + b->backxrb->ximage->bytes_per_line * y; 2269 XDITHER_SETUP(y); 2270 2271 /* read row from 3Dfx frame buffer */ 2272 grLfbReadRegion( GR_BUFFER_FRONTBUFFER, 2273 0, b->FXctx->height-(b->mesa_buffer.Height-y), 2274 b->mesa_buffer.Width, 1, 2275 0, 2276 pixbuf ); 2277 2278 /* write to XImage back buffer */ 2279 for (x=0;x<b->mesa_buffer.Width;x++) { 2280 GLubyte r = (pixbuf[x] & 0xf800) >> 8; 2281 GLubyte g = (pixbuf[x] & 0x07e0) >> 3; 2282 GLubyte b = (pixbuf[x] & 0x001f) << 3; 2283 *ptr++ = XDITHER( x, r, g, b); 2284 } 2285 } 2286 } 2287 else { 2288 /* General case: slow! */ 2289 for (y=0;y<b->mesa_buffer.Height;y++) { 2290 /* read row from 3Dfx frame buffer */ 2291 grLfbReadRegion( GR_BUFFER_FRONTBUFFER, 2292 0, b->FXctx->height-(b->mesa_buffer.Height-y), 2293 b->mesa_buffer.Width, 1, 2294 0, 2295 pixbuf ); 2296 2297 /* write to XImage back buffer */ 2298 for (x=0;x<b->mesa_buffer.Width;x++) { 2299 XMesaPutPixel(b->backxrb->ximage,x,y, 2300 xmesa_color_to_pixel(ctx, 2301 (pixbuf[x] & 0xf800) >> 8, 2302 (pixbuf[x] & 0x07e0) >> 3, 2303 (pixbuf[x] & 0x001f) << 3, 2304 0xff, 2305 b->xm_visual->undithered_pf)); 2306 } 2307 } 2308 } 2309 /* grLfbWriteColorFormat(GR_COLORFORMAT_ABGR); */ 2310} 2311#endif 2312 2313 2314/* 2315 * Copy the back buffer to the front buffer. If there's no back buffer 2316 * this is a no-op. 2317 */ 2318void XMesaSwapBuffers( XMesaBuffer b ) 2319{ 2320 GET_CURRENT_CONTEXT(ctx); 2321 2322 /* If we're swapping the buffer associated with the current context 2323 * we have to flush any pending rendering commands first. 2324 */ 2325 if (ctx && ctx->DrawBuffer == &(b->mesa_buffer)) 2326 _mesa_notifySwapBuffers(ctx); 2327 2328 if (b->db_state) { 2329#ifdef FX 2330 if (b->FXctx) { 2331 fxMesaSwapBuffers(); 2332 2333 if (b->FXwindowHack) 2334 FXgetImage(b); 2335 else 2336 return; 2337 } 2338#endif 2339 if (b->backxrb->ximage) { 2340 /* Copy Ximage from host's memory to server's window */ 2341#if defined(USE_XSHM) && !defined(XFree86Server) 2342 if (b->shm) { 2343 /*_glthread_LOCK_MUTEX(_xmesa_lock);*/ 2344 XShmPutImage( b->xm_visual->display, b->frontxrb->pixmap, 2345 b->swapgc, 2346 b->backxrb->ximage, 0, 0, 2347 0, 0, b->mesa_buffer.Width, b->mesa_buffer.Height, 2348 False ); 2349 /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/ 2350 } 2351 else 2352#endif 2353 { 2354 /*_glthread_LOCK_MUTEX(_xmesa_lock);*/ 2355 XMesaPutImage( b->xm_visual->display, b->frontxrb->pixmap, 2356 b->swapgc, 2357 b->backxrb->ximage, 0, 0, 2358 0, 0, b->mesa_buffer.Width, b->mesa_buffer.Height ); 2359 /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/ 2360 } 2361 } 2362 else { 2363 /* Copy pixmap to window on server */ 2364 /*_glthread_LOCK_MUTEX(_xmesa_lock);*/ 2365 XMesaCopyArea( b->xm_visual->display, 2366 b->backxrb->pixmap, /* source drawable */ 2367 b->frontxrb->pixmap, /* dest. drawable */ 2368 b->swapgc, 2369 0, 0, b->mesa_buffer.Width, b->mesa_buffer.Height, 2370 0, 0 /* dest region */ 2371 ); 2372 /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/ 2373 } 2374 } 2375#if !defined(XFree86Server) 2376 XSync( b->xm_visual->display, False ); 2377#endif 2378} 2379 2380 2381 2382/* 2383 * Copy sub-region of back buffer to front buffer 2384 */ 2385void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height ) 2386{ 2387 GET_CURRENT_CONTEXT(ctx); 2388 2389 /* If we're swapping the buffer associated with the current context 2390 * we have to flush any pending rendering commands first. 2391 */ 2392 if (ctx && ctx->DrawBuffer == &(b->mesa_buffer)) 2393 _mesa_notifySwapBuffers(ctx); 2394 2395 if (b->db_state) { 2396 int yTop = b->mesa_buffer.Height - y - height; 2397#ifdef FX 2398 if (b->FXctx) { 2399 fxMesaSwapBuffers(); 2400 if (b->FXwindowHack) 2401 FXgetImage(b); 2402 else 2403 return; 2404 } 2405#endif 2406 if (b->backxrb->ximage) { 2407 /* Copy Ximage from host's memory to server's window */ 2408#if defined(USE_XSHM) && !defined(XFree86Server) 2409 if (b->shm) { 2410 /* XXX assuming width and height aren't too large! */ 2411 XShmPutImage( b->xm_visual->display, b->frontxrb->pixmap, 2412 b->swapgc, 2413 b->backxrb->ximage, x, yTop, 2414 x, yTop, width, height, False ); 2415 /* wait for finished event??? */ 2416 } 2417 else 2418#endif 2419 { 2420 /* XXX assuming width and height aren't too large! */ 2421 XMesaPutImage( b->xm_visual->display, b->frontxrb->pixmap, 2422 b->swapgc, 2423 b->backxrb->ximage, x, yTop, 2424 x, yTop, width, height ); 2425 } 2426 } 2427 else { 2428 /* Copy pixmap to window on server */ 2429 XMesaCopyArea( b->xm_visual->display, 2430 b->backxrb->pixmap, /* source drawable */ 2431 b->frontxrb->pixmap, /* dest. drawable */ 2432 b->swapgc, 2433 x, yTop, width, height, /* source region */ 2434 x, yTop /* dest region */ 2435 ); 2436 } 2437 } 2438} 2439 2440 2441/* 2442 * Return a pointer to the XMesa backbuffer Pixmap or XImage. This function 2443 * is a way to get "under the hood" of X/Mesa so one can manipulate the 2444 * back buffer directly. 2445 * Output: pixmap - pointer to back buffer's Pixmap, or 0 2446 * ximage - pointer to back buffer's XImage, or NULL 2447 * Return: GL_TRUE = context is double buffered 2448 * GL_FALSE = context is single buffered 2449 */ 2450GLboolean XMesaGetBackBuffer( XMesaBuffer b, 2451 XMesaPixmap *pixmap, 2452 XMesaImage **ximage ) 2453{ 2454 if (b->db_state) { 2455 if (pixmap) *pixmap = b->backxrb->pixmap; 2456 if (ximage) *ximage = b->backxrb->ximage; 2457 return GL_TRUE; 2458 } 2459 else { 2460 *pixmap = 0; 2461 *ximage = NULL; 2462 return GL_FALSE; 2463 } 2464} 2465 2466 2467/* 2468 * Return the depth buffer associated with an XMesaBuffer. 2469 * Input: b - the XMesa buffer handle 2470 * Output: width, height - size of buffer in pixels 2471 * bytesPerValue - bytes per depth value (2 or 4) 2472 * buffer - pointer to depth buffer values 2473 * Return: GL_TRUE or GL_FALSE to indicate success or failure. 2474 */ 2475GLboolean XMesaGetDepthBuffer( XMesaBuffer b, GLint *width, GLint *height, 2476 GLint *bytesPerValue, void **buffer ) 2477{ 2478 struct gl_renderbuffer *rb 2479 = b->mesa_buffer.Attachment[BUFFER_DEPTH].Renderbuffer; 2480 if (!rb || !rb->Data) { 2481 *width = 0; 2482 *height = 0; 2483 *bytesPerValue = 0; 2484 *buffer = 0; 2485 return GL_FALSE; 2486 } 2487 else { 2488 *width = b->mesa_buffer.Width; 2489 *height = b->mesa_buffer.Height; 2490 *bytesPerValue = b->mesa_buffer.Visual.depthBits <= 16 2491 ? sizeof(GLushort) : sizeof(GLuint); 2492 *buffer = rb->Data; 2493 return GL_TRUE; 2494 } 2495} 2496 2497 2498void XMesaFlush( XMesaContext c ) 2499{ 2500 if (c && c->xm_visual) { 2501#ifdef XFree86Server 2502 /* NOT_NEEDED */ 2503#else 2504 XSync( c->xm_visual->display, False ); 2505#endif 2506 } 2507} 2508 2509 2510 2511const char *XMesaGetString( XMesaContext c, int name ) 2512{ 2513 (void) c; 2514 if (name==XMESA_VERSION) { 2515 return "5.0"; 2516 } 2517 else if (name==XMESA_EXTENSIONS) { 2518 return ""; 2519 } 2520 else { 2521 return NULL; 2522 } 2523} 2524 2525 2526 2527XMesaBuffer XMesaFindBuffer( XMesaDisplay *dpy, XMesaDrawable d ) 2528{ 2529 XMesaBuffer b; 2530 for (b=XMesaBufferList; b; b=b->Next) { 2531 if (b->frontxrb->pixmap==d && b->display==dpy) { 2532 return b; 2533 } 2534 } 2535 return NULL; 2536} 2537 2538 2539 2540/* 2541 * Look for XMesaBuffers whose X window has been destroyed. 2542 * Deallocate any such XMesaBuffers. 2543 */ 2544void XMesaGarbageCollect( void ) 2545{ 2546 XMesaBuffer b, next; 2547 for (b=XMesaBufferList; b; b=next) { 2548 next = b->Next; 2549 if (b->display && b->frontxrb->pixmap && b->type == WINDOW) { 2550#ifdef XFree86Server 2551 /* NOT_NEEDED */ 2552#else 2553 XSync(b->display, False); 2554 if (!window_exists( b->display, b->frontxrb->pixmap )) { 2555 /* found a dead window, free the ancillary info */ 2556 XMesaDestroyBuffer( b ); 2557 } 2558#endif 2559 } 2560 } 2561} 2562 2563 2564void XMesaReset( void ) 2565{ 2566 while (XMesaBufferList) 2567 XMesaDestroyBuffer(XMesaBufferList); 2568 2569 XMesaBufferList = NULL; 2570} 2571 2572 2573unsigned long XMesaDitherColor( XMesaContext xmesa, GLint x, GLint y, 2574 GLfloat red, GLfloat green, 2575 GLfloat blue, GLfloat alpha ) 2576{ 2577 GLcontext *ctx = &xmesa->mesa; 2578 GLint r = (GLint) (red * 255.0F); 2579 GLint g = (GLint) (green * 255.0F); 2580 GLint b = (GLint) (blue * 255.0F); 2581 GLint a = (GLint) (alpha * 255.0F); 2582 2583 switch (xmesa->pixelformat) { 2584 case PF_Index: 2585 return 0; 2586 case PF_Truecolor: 2587 { 2588 unsigned long p; 2589 PACK_TRUECOLOR( p, r, g, b ); 2590 return p; 2591 } 2592 case PF_8A8B8G8R: 2593 return PACK_8A8B8G8R( r, g, b, a ); 2594 case PF_8A8R8G8B: 2595 return PACK_8A8R8G8B( r, g, b, a ); 2596 case PF_8R8G8B: 2597 return PACK_8R8G8B( r, g, b ); 2598 case PF_5R6G5B: 2599 return PACK_5R6G5B( r, g, b ); 2600 case PF_Dither: 2601 { 2602 DITHER_SETUP; 2603 return DITHER( x, y, r, g, b ); 2604 } 2605 case PF_1Bit: 2606 /* 382 = (3*255)/2 */ 2607 return ((r+g+b) > 382) ^ xmesa->xm_visual->bitFlip; 2608 case PF_HPCR: 2609 return DITHER_HPCR(x, y, r, g, b); 2610 case PF_Lookup: 2611 { 2612 LOOKUP_SETUP; 2613 return LOOKUP( r, g, b ); 2614 } 2615 case PF_Grayscale: 2616 return GRAY_RGB( r, g, b ); 2617 case PF_Dither_5R6G5B: 2618 /* fall through */ 2619 case PF_Dither_True: 2620 { 2621 unsigned long p; 2622 PACK_TRUEDITHER(p, x, y, r, g, b); 2623 return p; 2624 } 2625 default: 2626 _mesa_problem(NULL, "Bad pixel format in XMesaDitherColor"); 2627 } 2628 return 0; 2629} 2630 2631 2632/* 2633 * This is typically called when the window size changes and we need 2634 * to reallocate the buffer's back/depth/stencil/accum buffers. 2635 */ 2636void XMesaResizeBuffers( XMesaBuffer b ) 2637{ 2638#ifdef XFree86Server 2639 GET_CURRENT_CONTEXT(ctx); 2640 xmesa_resize_buffers(ctx, &(b->mesa_buffer), 0, 0); 2641#else 2642 Window root; 2643 int xpos, ypos; 2644 unsigned int width, height, bw, depth; 2645 GET_CURRENT_CONTEXT(ctx); 2646 XGetGeometry( b->xm_visual->display, b->frontxrb->pixmap, 2647 &root, &xpos, &ypos, &width, &height, &bw, &depth); 2648 xmesa_resize_buffers(ctx, &(b->mesa_buffer), width, height); 2649#endif 2650} 2651 2652