xm_api.c revision 48f5deab94be832a782a440f55a7bc742d50a62f
19fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org/* 29e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Mesa 3-D graphics library 39e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Version: 6.5.2 49e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * 59e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 69e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * 79e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 89e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * copy of this software and associated documentation files (the "Software"), 99e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * to deal in the Software without restriction, including without limitation 109e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense, 119e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * and/or sell copies of the Software, and to permit persons to whom the 129e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Software is furnished to do so, subject to the following conditions: 139e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * 149e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * The above copyright notice and this permission notice shall be included 159e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * in all copies or substantial portions of the Software. 169e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * 179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 219e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 239e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */ 249e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 259e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/** 269e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * \file xm_api.c 279e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * 289e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * All the XMesa* API functions. 299e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * 309e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * 319e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * NOTES: 329e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * 339e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * The window coordinate system origin (0,0) is in the lower-left corner 349e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * of the window. X11's window coordinate origin is in the upper-left 359e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * corner of the window. Therefore, most drawing functions in this 369e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * file have to flip Y coordinates. 379e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * 389e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Define USE_XSHM in the Makefile with -DUSE_XSHM if you want to compile 399e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * in support for the MIT Shared Memory extension. If enabled, when you 409e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * use an Ximage for the back buffer in double buffered mode, the "swap" 419e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * operation will be faster. You must also link with -lXext. 429e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * 439e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Byte swapping: If the Mesa host and the X display use a different 449e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * byte order then there's some trickiness to be aware of when using 459e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * XImages. The byte ordering used for the XImage is that of the X 469e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * display, not the Mesa host. 479e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * The color-to-pixel encoding for True/DirectColor must be done 489e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * according to the display's visual red_mask, green_mask, and blue_mask. 499e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * If XPutPixel is used to put a pixel into an XImage then XPutPixel will 509e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * do byte swapping if needed. If one wants to directly "poke" the pixel 519e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * into the XImage's buffer then the pixel must be byte swapped first. In 529e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Mesa, when byte swapping is needed we use the PF_TRUECOLOR pixel format 539e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * and use XPutPixel everywhere except in the implementation of 549e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * glClear(GL_COLOR_BUFFER_BIT). We want this function to be fast so 559e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * instead of using XPutPixel we "poke" our values after byte-swapping 569e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * the clear pixel value if needed. 579e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * 589e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */ 599e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 609e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#ifdef __CYGWIN__ 619e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#undef WIN32 629e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#undef __WIN32__ 639e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#endif 649e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 659e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "glxheader.h" 669e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "GL/xmesa.h" 679e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "xmesaP.h" 689e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "context.h" 699e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "extensions.h" 709e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "framebuffer.h" 719e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "glthread.h" 729e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "imports.h" 739e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "macros.h" 749e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "renderbuffer.h" 759e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "swrast/swrast.h" 769e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "swrast_setup/swrast_setup.h" 779e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "vbo/vbo.h" 789e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "tnl/tnl.h" 799e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "tnl/t_context.h" 809e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "tnl/t_pipeline.h" 819e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "drivers/common/driverfuncs.h" 829e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 839e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#ifdef XFree86Server 849e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include <GL/glxtokens.h> 85c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif 86c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 87c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com/** 889e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Global X driver lock 899e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */ 909e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org_glthread_Mutex _xmesa_lock; 919e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 929e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 939e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 94c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com/** 95c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com * Lookup tables for HPCR pixel format: 96c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com */ 974d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.orgstatic short hpcr_rgbTbl[3][256] = { 984d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org{ 999e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 1009e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 1019e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 1029e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 1039e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 1049e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 1059e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 1069e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 1079e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 1089e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 1099e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 1109e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 1119e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 1129e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 1139e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 1149e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239 1159e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org}, 1169e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{ 1179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 1189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 1199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 1209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 1219e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 1229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 1233847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 1243847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 1253847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 1269e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 1279e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 1289e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 1299e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 1309e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 1319e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 1329e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239 1339e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org}, 1349e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{ 1359e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 1369e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47, 1379e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 48, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, 1389e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63, 1399e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 64, 64, 65, 65, 66, 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 1409e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 72, 72, 73, 73, 74, 74, 75, 75, 76, 76, 77, 77, 78, 78, 79, 79, 1419e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 80, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, 86, 86, 87, 87, 1429e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 1439e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 1449e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 1459e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 1469e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 1479e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 1489e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 1499e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 1509e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223 1519e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org} 1529e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org}; 1539e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 1549e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 1559e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 1569e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/**********************************************************************/ 1577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org/***** X Utility Functions *****/ 1587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org/**********************************************************************/ 1597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 16034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 16134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org/** 16234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org * Return the host's byte order as LSBFirst or MSBFirst ala X. 1637c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org */ 1647c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org#ifndef XFree86Server 1657c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.orgstatic int host_byte_order( void ) 166ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org{ 167ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org int i = 1; 1689e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org char *cptr = (char *) &i; 1699e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org return (*cptr==1) ? LSBFirst : MSBFirst; 1709e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org} 1719e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#endif 17231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 17331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 17431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org/** 1759e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Check if the X Shared Memory extension is available. 1769e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Return: 0 = not available 1779e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * 1 = shared XImage support available 1789e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * 2 = shared Pixmap support available also 1799e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */ 1809e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgstatic int check_for_xshm( XMesaDisplay *display ) 1819e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{ 1829e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#if defined(XFree86Server) 1839e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org return 0; 1849e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#elif defined(USE_XSHM) 1859e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org int major, minor, ignore; 1869e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org Bool pixmaps; 1879e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 1889e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) { 1899e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) { 1909e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org return (pixmaps==True) ? 2 : 1; 1919e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 1929e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org else { 1939e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org return 0; 1949e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 1959e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 1969e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org else { 1979e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org return 0; 198c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 199c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#else 200c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com /* No XSHM support */ 201c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return 0; 202c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif 2034d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org} 2044d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org 2059e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 2069e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/** 2079e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Apply gamma correction to an intensity value in [0..max]. Return the 2089e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * new intensity value. 2099e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */ 2109e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgstatic GLint 2119e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orggamma_adjust( GLfloat gamma, GLint value, GLint max ) 2129e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{ 2139e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (gamma == 1.0) { 2149e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org return value; 2159e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 2169e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org else { 2179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org double x = (double) value / (double) max; 2189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org return IROUND_POS((GLfloat) max * _mesa_pow(x, 1.0F/gamma)); 2199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 2209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org} 2219e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 2229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 2239e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 2249e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/** 2259e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Return the true number of bits per pixel for XImages. 2269e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * For example, if we request a 24-bit deep visual we may actually need/get 2279e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * 32bpp XImages. This function returns the appropriate bpp. 2289e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Input: dpy - the X display 2299e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * visinfo - desribes the visual to be used for XImages 2309e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Return: true number of bits per pixel for XImages 2319e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */ 2329e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgstatic int 2339e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgbits_per_pixel( XMesaVisual xmv ) 2349e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{ 2359e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#ifdef XFree86Server 2369e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org const int depth = xmv->nplanes; 2379e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org int i; 2389e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org assert(depth > 0); 2399e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org for (i = 0; i < screenInfo.numPixmapFormats; i++) { 2409e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (screenInfo.formats[i].depth == depth) 2419e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org return screenInfo.formats[i].bitsPerPixel; 2429e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 2433847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com return depth; /* should never get here, but this should be safe */ 2443847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com#else 2453847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com XMesaDisplay *dpy = xmv->display; 2463847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com XMesaVisualInfo visinfo = xmv->visinfo; 2473847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com XMesaImage *img; 2489e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org int bitsPerPixel; 2499e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* Create a temporary XImage */ 2509e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org img = XCreateImage( dpy, visinfo->visual, visinfo->depth, 2519e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org ZPixmap, 0, /*format, offset*/ 2529e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org (char*) MALLOC(8), /*data*/ 2539e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 1, 1, /*width, height*/ 2549e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 32, /*bitmap_pad*/ 2559e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 0 /*bytes_per_line*/ 2569e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org ); 2579e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org assert(img); 2589e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* grab the bits/pixel value */ 2599e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org bitsPerPixel = img->bits_per_pixel; 2609e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* free the XImage */ 2619e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org _mesa_free( img->data ); 2629e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org img->data = NULL; 2639e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org XMesaDestroyImage( img ); 2649e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org return bitsPerPixel; 2659e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#endif 2669e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org} 2679e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 2689e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 2699e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 270c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com/* 271c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com * Determine if a given X window ID is valid (window exists). 272c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com * Do this by calling XGetWindowAttributes() for the window and 273c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com * checking if we catch an X error. 274c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com * Input: dpy - the display 275c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com * win - the window to check for existance 276c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com * Return: GL_TRUE - window exists 277c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com * GL_FALSE - window doesn't exist 278c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com */ 279c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#ifndef XFree86Server 280c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic GLboolean WindowExistsFlag; 281c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 282c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic int window_exists_err_handler( XMesaDisplay* dpy, XErrorEvent* xerr ) 283c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com{ 284c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com (void) dpy; 285c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (xerr->error_code == BadWindow) { 286c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com WindowExistsFlag = GL_FALSE; 287c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 288c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return 0; 2899e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org} 290c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2919e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgstatic GLboolean window_exists( XMesaDisplay *dpy, Window win ) 2929e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{ 293c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com XWindowAttributes wa; 2949e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org int (*old_handler)( XMesaDisplay*, XErrorEvent* ); 2959e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org WindowExistsFlag = GL_TRUE; 296c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com old_handler = XSetErrorHandler(window_exists_err_handler); 2979e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org XGetWindowAttributes( dpy, win, &wa ); /* dummy request */ 298c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org XSetErrorHandler(old_handler); 299c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org return WindowExistsFlag; 300c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org} 3019e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#endif 3029e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 3039e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 3049e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 3059e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/** 3069e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Return the size of the window (or pixmap) that corresponds to the 3079e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * given XMesaBuffer. 3089e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * \param width returns width in pixels 3099e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * \param height returns height in pixels 3109e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */ 3119e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgvoid 312c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comxmesa_get_window_size(XMesaDisplay *dpy, XMesaBuffer b, 313c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com GLuint *width, GLuint *height) 314c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com{ 315c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#ifdef XFree86Server 3169e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *width = MIN2(b->frontxrb->drawable->width, MAX_WIDTH); 3179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *height = MIN2(b->frontxrb->drawable->height, MAX_HEIGHT); 3189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#else 3199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org Window root; 3209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org Status stat; 3219e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org int xpos, ypos; 3229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org unsigned int w, h, bw, depth; 3239e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 3249e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org _glthread_LOCK_MUTEX(_xmesa_lock); 3259e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org XSync(b->xm_visual->display, 0); /* added for Chromium */ 3269fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org stat = XGetGeometry(dpy, b->frontxrb->pixmap, &root, &xpos, &ypos, 3279fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org &w, &h, &bw, &depth); 3289fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org _glthread_UNLOCK_MUTEX(_xmesa_lock); 3299fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org 3309fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org if (stat) { 3319fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org *width = w; 3329fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org *height = h; 3337c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org } 3349fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org else { 3359fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org /* probably querying a window that's recently been destroyed */ 3369fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org _mesa_warning(NULL, "XGetGeometry failed!\n"); 3379fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org *width = *height = 1; 3389fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org } 3394d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org#endif 3404d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org} 3419e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 3427c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org 3439e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 3449e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/**********************************************************************/ 3459e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/***** Linked list of XMesaBuffers *****/ 3469e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/**********************************************************************/ 3479e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 3489e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgstatic XMesaBuffer XMesaBufferList = NULL; 3497c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org 3509e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 3519e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/** 3529e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Allocate a new XMesaBuffer object which corresponds to the given drawable. 3539e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Note that XMesaBuffer is derived from GLframebuffer. 3549e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * The new XMesaBuffer will not have any size (Width=Height=0). 3559e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * 3569e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * \param d the corresponding X drawable (window or pixmap) 3577c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org * \param type either WINDOW, PIXMAP or PBUFFER, describing d 3589e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * \param vis the buffer's visual 3599e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * \param cmap the window's colormap, if known. 3609e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * \return new XMesaBuffer or NULL if any problem 3619e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */ 3629e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgstatic XMesaBuffer 3639e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgcreate_xmesa_buffer(XMesaDrawable d, BufferType type, 3647c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org XMesaVisual vis, XMesaColormap cmap) 3659e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{ 3669e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org GLboolean swAlpha; 3679e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org XMesaBuffer b; 3689e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 3699e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER); 3709e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 3719e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer); 3727c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org if (!b) 3739e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org return NULL; 3749e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 3759e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org b->display = vis->display; 3769e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org b->xm_visual = vis; 3779e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org b->type = type; 3789e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org b->cmap = cmap; 3797c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org 3809e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org _mesa_initialize_framebuffer(&b->mesa_buffer, &vis->mesa_visual); 3819e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 3829e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* 3839e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Front renderbuffer 3849e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */ 3859e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org b->frontxrb = xmesa_new_renderbuffer(NULL, 0, &vis->mesa_visual, 3869e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org GL_FALSE); 3877c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org if (!b->frontxrb) { 3889e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org _mesa_free(b); 3899e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org return NULL; 3909e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 3919e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org b->frontxrb->Parent = b; 3929e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org b->frontxrb->drawable = d; 3939e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org b->frontxrb->pixmap = (XMesaPixmap) d; 3947c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_FRONT_LEFT, 3959e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org &b->frontxrb->Base); 3969e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 3979e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* 3983847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com * Back renderbuffer 3993847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com */ 4003847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com if (vis->mesa_visual.doubleBufferMode) { 4017c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org b->backxrb = xmesa_new_renderbuffer(NULL, 0, &vis->mesa_visual, 4023847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com GL_TRUE); 4033847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com if (!b->backxrb) { 4043847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com /* XXX free front xrb too */ 4059e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org _mesa_free(b); 4069e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org return NULL; 4079e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 4087b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org b->backxrb->Parent = b; 4097b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org /* determine back buffer implementation */ 4107b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org b->db_mode = vis->ximage_flag ? BACK_XIMAGE : BACK_PIXMAP; 4117b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org 4127b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_BACK_LEFT, 4137b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org &b->backxrb->Base); 4147b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org } 4157b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org 4167b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org /* 4179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Software alpha planes 4189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */ 4199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (vis->mesa_visual.alphaBits > 0 4209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org && vis->undithered_pf != PF_8A8B8G8R 4219e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org && vis->undithered_pf != PF_8A8R8G8B) { 4229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* Visual has alpha, but pixel format doesn't support it. 423c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com * We'll use an alpha renderbuffer wrapper. 424c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com */ 425c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com swAlpha = GL_TRUE; 426c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 427c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com else { 428c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com swAlpha = GL_FALSE; 429c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 4309e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 4319e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* 4329e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Other renderbuffer (depth, stencil, etc) 4339e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */ 4349e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org _mesa_add_soft_renderbuffers(&b->mesa_buffer, 4359e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org GL_FALSE, /* color */ 4369e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org vis->mesa_visual.haveDepthBuffer, 4379e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org vis->mesa_visual.haveStencilBuffer, 4389e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org vis->mesa_visual.haveAccumBuffer, 4399e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org swAlpha, 4409e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org vis->mesa_visual.numAuxBuffers > 0 ); 4419e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 4429e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* insert buffer into linked list */ 4439e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org b->Next = XMesaBufferList; 4449e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org XMesaBufferList = b; 4459e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 4469e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org return b; 4479e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org} 4489e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 4499e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 4509e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/** 4519e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Find an XMesaBuffer by matching X display and colormap but NOT matching 4529e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * the notThis buffer. 4539e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */ 4549e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgstatic XMesaBuffer 4559e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgfind_xmesa_buffer(XMesaDisplay *dpy, XMesaColormap cmap, XMesaBuffer notThis) 4569e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{ 4579e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org XMesaBuffer b; 458c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (b=XMesaBufferList; b; b=b->Next) { 4594d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org if (b->display==dpy && b->cmap==cmap && b!=notThis) { 4609e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org return b; 4619e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 4629e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 4639e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org return NULL; 4649e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org} 4659e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 4669e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 4679e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/** 4689e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Free an XMesaBuffer, remove from linked list, perhaps free X colormap 4699e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * entries. 4703847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com */ 4719e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgstatic void 4729e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgfree_xmesa_buffer(int client, XMesaBuffer buffer) 4739e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{ 4749e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org XMesaBuffer prev = NULL, b; 4759e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org (void) client; 4769e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org for (b=XMesaBufferList; b; b=b->Next) { 4779e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (b==buffer) { 4789e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* unlink bufer from list */ 4799e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (prev) 4807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org prev->Next = buffer->Next; 4817c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org else 4829e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org XMesaBufferList = buffer->Next; 4839e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* Check to free X colors */ 4849e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (buffer->num_alloced>0) { 4859e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* If no other buffer uses this X colormap then free the colors. */ 4869e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (!find_xmesa_buffer(buffer->display, buffer->cmap, buffer)) { 487ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org#ifdef XFree86Server 48831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org (void)FreeColors(buffer->cmap, client, 4899e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org buffer->num_alloced, buffer->alloced_colors, 4909e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 0); 4919e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#else 4923847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com XFreeColors(buffer->display, buffer->cmap, 4939e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org buffer->alloced_colors, buffer->num_alloced, 0); 4949e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#endif 4959e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 4969e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 4979e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 4989e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org _mesa_free_framebuffer_data(&buffer->mesa_buffer); 4999e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org _mesa_free(buffer); 5009e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 5019e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org return; 502c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 503c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com /* continue search */ 504c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com prev = b; 5059e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 5069e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* buffer not found in XMesaBufferList */ 5079e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org _mesa_problem(NULL,"free_xmesa_buffer() - buffer not found\n"); 5089e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org} 5099e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 5109e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 5119e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/** 5129e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Copy X color table stuff from one XMesaBuffer to another. 5139e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */ 5149e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgstatic void 5159e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgcopy_colortable_info(XMesaBuffer dst, const XMesaBuffer src) 5169e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{ 5179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org MEMCPY(dst->color_table, src->color_table, sizeof(src->color_table)); 5189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org MEMCPY(dst->pixel_to_r, src->pixel_to_r, sizeof(src->pixel_to_r)); 5199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org MEMCPY(dst->pixel_to_g, src->pixel_to_g, sizeof(src->pixel_to_g)); 5209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org MEMCPY(dst->pixel_to_b, src->pixel_to_b, sizeof(src->pixel_to_b)); 5219e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org dst->num_alloced = src->num_alloced; 5229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org MEMCPY(dst->alloced_colors, src->alloced_colors, 5239e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org sizeof(src->alloced_colors)); 5249e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org} 5259e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 5269e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 5279e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 5289e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/**********************************************************************/ 5299e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/***** Misc Private Functions *****/ 5309e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/**********************************************************************/ 5319e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 5329e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 5339e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/** 5349e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * A replacement for XAllocColor. This function should never 5359e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * fail to allocate a color. When XAllocColor fails, we return 5369e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * the nearest matching color. If we have to allocate many colors 5379e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * this function isn't too efficient; the XQueryColors() could be 5389e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * done just once. 5399e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Written by Michael Pichler, Brian Paul, Mark Kilgard 5409e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Input: dpy - X display 541e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org * cmap - X colormap 542e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org * cmapSize - size of colormap 543e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org * In/Out: color - the XColor struct 544e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org * Output: exact - 1=exact color match, 0=closest match 545e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org * alloced - 1=XAlloc worked, 0=XAlloc failed 546e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org */ 547e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.orgstatic void 5489e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgnoFaultXAllocColor( int client, 5499e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org XMesaDisplay *dpy, 5509e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org XMesaColormap cmap, 5519e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org int cmapSize, 5529e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org XMesaColor *color, 5539e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org int *exact, int *alloced ) 5549e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{ 5559e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#ifdef XFree86Server 5569e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org Pixel *ppixIn; 5579e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org xrgb *ctable; 5589e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#else 5599e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* we'll try to cache ctable for better remote display performance */ 5609e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org static Display *prevDisplay = NULL; 5619e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org static XMesaColormap prevCmap = 0; 562c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static int prevCmapSize = 0; 563c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static XMesaColor *ctable = NULL; 564c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif 565c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com XMesaColor subColor; 566c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int i, bestmatch; 567c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com double mindist; /* 3*2^16^2 exceeds long int precision. */ 568c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 569c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com (void) client; 570c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 571c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com /* First try just using XAllocColor. */ 5729e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#ifdef XFree86Server 5739e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (AllocColor(cmap, 5749e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org &color->red, &color->green, &color->blue, 5759e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org &color->pixel, 5769e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org client) == Success) 5779e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#else 57831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org if (XAllocColor(dpy, cmap, color)) 57931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org#endif 58031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org { 58131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org *exact = 1; 58231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org *alloced = 1; 58331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org return; 58431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org } 58531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 58631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org /* Alloc failed, search for closest match */ 58731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 58831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org /* Retrieve color table entries. */ 58931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org /* XXX alloca candidate. */ 59031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org#ifdef XFree86Server 59131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org ppixIn = (Pixel *) MALLOC(cmapSize * sizeof(Pixel)); 59231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org ctable = (xrgb *) MALLOC(cmapSize * sizeof(xrgb)); 59331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org for (i = 0; i < cmapSize; i++) { 59431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org ppixIn[i] = i; 59531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org } 5969e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org QueryColors(cmap, cmapSize, ppixIn, ctable); 5979e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#else 5989e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (prevDisplay != dpy || prevCmap != cmap 5999e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org || prevCmapSize != cmapSize || !ctable) { 6009e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* free previously cached color table */ 6019e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (ctable) 6029e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org _mesa_free(ctable); 6039e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* Get the color table from X */ 6049e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org ctable = (XMesaColor *) MALLOC(cmapSize * sizeof(XMesaColor)); 6059e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org assert(ctable); 6069e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org for (i = 0; i < cmapSize; i++) { 6079e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org ctable[i].pixel = i; 6089e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 6099e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org XQueryColors(dpy, cmap, ctable, cmapSize); 6109e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org prevDisplay = dpy; 6119e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org prevCmap = cmap; 6129e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org prevCmapSize = cmapSize; 6139e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 6149e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#endif 6159e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 6169e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* Find best match. */ 6179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org bestmatch = -1; 6189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org mindist = 0.0; 6199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org for (i = 0; i < cmapSize; i++) { 6209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org double dr = 0.30 * ((double) color->red - (double) ctable[i].red); 6219e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org double dg = 0.59 * ((double) color->green - (double) ctable[i].green); 6229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org double db = 0.11 * ((double) color->blue - (double) ctable[i].blue); 6237943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org double dist = dr * dr + dg * dg + db * db; 6247943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org if (bestmatch < 0 || dist < mindist) { 6257943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org bestmatch = i; 6267943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org mindist = dist; 6277943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org } 6287943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org } 6297943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org 6307943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org /* Return result. */ 6317943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org subColor.red = ctable[bestmatch].red; 6327943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org subColor.green = ctable[bestmatch].green; 6337943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org subColor.blue = ctable[bestmatch].blue; 6347943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org /* Try to allocate the closest match color. This should only 6357943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org * fail if the cell is read/write. Otherwise, we're incrementing 6367943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org * the cell's reference count. 6377943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org */ 6387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org#ifdef XFree86Server 6397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (AllocColor(cmap, 6407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org &subColor.red, &subColor.green, &subColor.blue, 6417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org &subColor.pixel, 6427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org client) == Success) { 643c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#else 644c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (XAllocColor(dpy, cmap, &subColor)) { 6457304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org#endif 6467304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org *alloced = 1; 6477304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 6487304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org else { 64934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org /* do this to work around a problem reported by Frank Ortega */ 65034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org subColor.pixel = (unsigned long) bestmatch; 65134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org subColor.red = ctable[bestmatch].red; 65234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org subColor.green = ctable[bestmatch].green; 65334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org subColor.blue = ctable[bestmatch].blue; 65434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org subColor.flags = DoRed | DoGreen | DoBlue; 65534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org *alloced = 0; 65634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 65734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org#ifdef XFree86Server 65834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org _mesa_free(ppixIn); 65934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org _mesa_free(ctable); 66034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org#else 66134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org /* don't free table, save it for next time */ 6627c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org#endif 6637c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org 6647c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org *color = subColor; 6657c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org *exact = 0; 6667c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org} 6677c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org 6687c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org 6697c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org 6707c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org/** 6719e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Do setup for PF_GRAYSCALE pixel format. 6729e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Note that buffer may be NULL. 6739e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */ 6749e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgstatic GLboolean 6759e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgsetup_grayscale(int client, XMesaVisual v, 6769e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org XMesaBuffer buffer, XMesaColormap cmap) 6779e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{ 6789e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) { 6799e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org return GL_FALSE; 6809e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 6819e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 6829e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (buffer) { 6839e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org XMesaBuffer prevBuffer; 6849e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 6859e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (!cmap) { 6869e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org return GL_FALSE; 6879e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 6889e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 6899e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org prevBuffer = find_xmesa_buffer(v->display, cmap, buffer); 6909e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (prevBuffer && 6919e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org (buffer->xm_visual->mesa_visual.rgbMode == 6929e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org prevBuffer->xm_visual->mesa_visual.rgbMode)) { 6939e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* Copy colormap stuff from previous XMesaBuffer which uses same 6949e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * X colormap. Do this to avoid time spent in noFaultXAllocColor. 6959e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */ 6969e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org copy_colortable_info(buffer, prevBuffer); 6979e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 6989e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org else { 6999e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* Allocate 256 shades of gray */ 7009e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org int gray; 7019e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org int colorsfailed = 0; 7029e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org for (gray=0;gray<256;gray++) { 7039e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org GLint r = gamma_adjust( v->RedGamma, gray, 255 ); 7049e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org GLint g = gamma_adjust( v->GreenGamma, gray, 255 ); 7059e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org GLint b = gamma_adjust( v->BlueGamma, gray, 255 ); 7069e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org int exact, alloced; 7079e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org XMesaColor xcol; 7089e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org xcol.red = (r << 8) | r; 7099e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org xcol.green = (g << 8) | g; 7109e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org xcol.blue = (b << 8) | b; 7119e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org noFaultXAllocColor( client, v->display, 7129e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org cmap, GET_COLORMAP_SIZE(v), 7139e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org &xcol, &exact, &alloced ); 7149e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (!exact) { 7159e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org colorsfailed++; 7169e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 7179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (alloced) { 7189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org assert(buffer->num_alloced<256); 7199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org buffer->alloced_colors[buffer->num_alloced] = xcol.pixel; 7209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org buffer->num_alloced++; 7219e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 7229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 7239e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /*OLD 7249e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org assert(gray < 576); 7259e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org buffer->color_table[gray*3+0] = xcol.pixel; 7269e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org buffer->color_table[gray*3+1] = xcol.pixel; 7279e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org buffer->color_table[gray*3+2] = xcol.pixel; 7289e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org assert(xcol.pixel < 65536); 7299e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org buffer->pixel_to_r[xcol.pixel] = gray * 30 / 100; 7309e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org buffer->pixel_to_g[xcol.pixel] = gray * 59 / 100; 7319e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org buffer->pixel_to_b[xcol.pixel] = gray * 11 / 100; 7329e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */ 7339e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org buffer->color_table[gray] = xcol.pixel; 7349e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org assert(xcol.pixel < 65536); 7359e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org buffer->pixel_to_r[xcol.pixel] = gray; 7369e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org buffer->pixel_to_g[xcol.pixel] = gray; 7379e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org buffer->pixel_to_b[xcol.pixel] = gray; 7389e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 7399e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 7409e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (colorsfailed && _mesa_getenv("MESA_DEBUG")) { 7419e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org _mesa_warning(NULL, 7429e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org "Note: %d out of 256 needed colors do not match exactly.\n", 7439e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org colorsfailed ); 7449e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 7459e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 7469e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 7479e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 7489e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org v->dithered_pf = PF_Grayscale; 7499e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org v->undithered_pf = PF_Grayscale; 7509e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org return GL_TRUE; 7519e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org} 7529e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 7539e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 7549e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 7559e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/** 7569e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Setup RGB rendering for a window with a PseudoColor, StaticColor, 7579e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * or 8-bit TrueColor visual visual. We try to allocate a palette of 225 7589e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * colors (5 red, 9 green, 5 blue) and dither to approximate a 24-bit RGB 7599e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * color. While this function was originally designed just for 8-bit 7609e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * visuals, it has also proven to work from 4-bit up to 16-bit visuals. 7619e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Dithering code contributed by Bob Mercier. 7629e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */ 763ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.orgstatic GLboolean 764c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgsetup_dithered_color(int client, XMesaVisual v, 7659e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org XMesaBuffer buffer, XMesaColormap cmap) 7669e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{ 7679e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) { 7689e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org return GL_FALSE; 7699e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 7709e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 7719e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (buffer) { 7729e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org XMesaBuffer prevBuffer; 7739e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 7749e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (!cmap) { 7759e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org return GL_FALSE; 7769e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 7779e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 7789e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org prevBuffer = find_xmesa_buffer(v->display, cmap, buffer); 7799e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (prevBuffer && 7809e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org (buffer->xm_visual->mesa_visual.rgbMode == 7819e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org prevBuffer->xm_visual->mesa_visual.rgbMode)) { 7829e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* Copy colormap stuff from previous, matching XMesaBuffer. 7839e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Do this to avoid time spent in noFaultXAllocColor. 7849e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */ 7859e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org copy_colortable_info(buffer, prevBuffer); 7869e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 7879e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org else { 7889e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* Allocate X colors and initialize color_table[], red_table[], etc */ 7899e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org int r, g, b, i; 7909e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org int colorsfailed = 0; 7919e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org for (r = 0; r < DITH_R; r++) { 7929e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org for (g = 0; g < DITH_G; g++) { 7939e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org for (b = 0; b < DITH_B; b++) { 7949e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org XMesaColor xcol; 7959e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org int exact, alloced; 7969e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org xcol.red =gamma_adjust(v->RedGamma, r*65535/(DITH_R-1),65535); 7979e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org xcol.green=gamma_adjust(v->GreenGamma, g*65535/(DITH_G-1),65535); 7989e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org xcol.blue =gamma_adjust(v->BlueGamma, b*65535/(DITH_B-1),65535); 7999e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org noFaultXAllocColor( client, v->display, 8009e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org cmap, GET_COLORMAP_SIZE(v), 8019e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org &xcol, &exact, &alloced ); 8029e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (!exact) { 8039e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org colorsfailed++; 8049e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 8059e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (alloced) { 8069e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org assert(buffer->num_alloced<256); 8079e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org buffer->alloced_colors[buffer->num_alloced] = xcol.pixel; 8089e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org buffer->num_alloced++; 8099e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 8109e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org i = DITH_MIX( r, g, b ); 8119e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org assert(i < 576); 8129e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org buffer->color_table[i] = xcol.pixel; 8139e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org assert(xcol.pixel < 65536); 8149e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org buffer->pixel_to_r[xcol.pixel] = r * 255 / (DITH_R-1); 8159e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org buffer->pixel_to_g[xcol.pixel] = g * 255 / (DITH_G-1); 8169e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org buffer->pixel_to_b[xcol.pixel] = b * 255 / (DITH_B-1); 8179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 8189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 8199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 8209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 8219e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (colorsfailed && _mesa_getenv("MESA_DEBUG")) { 8229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org _mesa_warning(NULL, 8239e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org "Note: %d out of %d needed colors do not match exactly.\n", 8249e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org colorsfailed, DITH_R * DITH_G * DITH_B ); 8259e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 8269e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 8279e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 8289e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 8299e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org v->dithered_pf = PF_Dither; 8309e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org v->undithered_pf = PF_Lookup; 8319e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org return GL_TRUE; 8329e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org} 8339e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 8349e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 8359e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/** 8369e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Setup for Hewlett Packard Color Recovery 8-bit TrueColor mode. 8379e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * HPCR simulates 24-bit color fidelity with an 8-bit frame buffer. 8389e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Special dithering tables have to be initialized. 8399e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */ 8409e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgstatic void 8419e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgsetup_8bit_hpcr(XMesaVisual v) 8429e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{ 8439e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* HP Color Recovery contributed by: Alex De Bruyn (ad@lms.be) 8449e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * To work properly, the atom _HP_RGB_SMOOTH_MAP_LIST must be defined 8459e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * on the root window AND the colormap obtainable by XGetRGBColormaps 8469e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * for that atom must be set on the window. (see also tkInitWindow) 8479e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * If that colormap is not set, the output will look stripy. 8489e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */ 8499e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 8509e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* Setup color tables with gamma correction */ 8519e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org int i; 8529e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org double g; 8539e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 8549e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org g = 1.0 / v->RedGamma; 8559e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org for (i=0; i<256; i++) { 8569e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org GLint red = IROUND_POS(255.0 * _mesa_pow( hpcr_rgbTbl[0][i]/255.0, g )); 8579e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org v->hpcr_rgbTbl[0][i] = CLAMP( red, 16, 239 ); 8589e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 859c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 860c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com g = 1.0 / v->GreenGamma; 861c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (i=0; i<256; i++) { 862c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com GLint green = IROUND_POS(255.0 * _mesa_pow( hpcr_rgbTbl[1][i]/255.0, g )); 8639e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org v->hpcr_rgbTbl[1][i] = CLAMP( green, 16, 239 ); 8649e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 8659e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 8669e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org g = 1.0 / v->BlueGamma; 867c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (i=0; i<256; i++) { 8689e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org GLint blue = IROUND_POS(255.0 * _mesa_pow( hpcr_rgbTbl[2][i]/255.0, g )); 8699e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org v->hpcr_rgbTbl[2][i] = CLAMP( blue, 32, 223 ); 8709e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 8719e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org v->undithered_pf = PF_HPCR; /* can't really disable dithering for now */ 8729e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org v->dithered_pf = PF_HPCR; 8739e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 8749e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* which method should I use to clear */ 8759e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* GL_FALSE: keep the ordinary method */ 8769e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* GL_TRUE : clear with dither pattern */ 8779e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org v->hpcr_clear_flag = _mesa_getenv("MESA_HPCR_CLEAR") ? GL_TRUE : GL_FALSE; 8789e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 8799e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org if (v->hpcr_clear_flag) { 8809e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org v->hpcr_clear_pixmap = XMesaCreatePixmap(v->display, 8819e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org DefaultRootWindow(v->display), 8829e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 16, 2, 8); 8839e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#ifndef XFree86Server 8849e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org v->hpcr_clear_ximage = XGetImage(v->display, v->hpcr_clear_pixmap, 8859e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 0, 0, 16, 2, AllPlanes, ZPixmap); 8869e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#endif 8879e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 8889e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org} 8899e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 8909e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 8919e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/** 8929e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Setup RGB rendering for a window with a True/DirectColor visual. 8939e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */ 8949e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgstatic void 8959e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgsetup_truecolor(XMesaVisual v, XMesaBuffer buffer, XMesaColormap cmap) 8969e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{ 8979e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org unsigned long rmask, gmask, bmask; 8989e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org (void) buffer; 8999e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org (void) cmap; 9009e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 9019e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* Compute red multiplier (mask) and bit shift */ 9029e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org v->rshift = 0; 9039e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org rmask = GET_REDMASK(v); 9049e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org while ((rmask & 1)==0) { 9059e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org v->rshift++; 9069e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org rmask = rmask >> 1; 9079e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 9089e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 9099e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* Compute green multiplier (mask) and bit shift */ 9109e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org v->gshift = 0; 9119e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org gmask = GET_GREENMASK(v); 9129e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org while ((gmask & 1)==0) { 9139e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org v->gshift++; 9149e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org gmask = gmask >> 1; 9159e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 9169e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 9179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* Compute blue multiplier (mask) and bit shift */ 9189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org v->bshift = 0; 9199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org bmask = GET_BLUEMASK(v); 9209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org while ((bmask & 1)==0) { 9219e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org v->bshift++; 9229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org bmask = bmask >> 1; 9239e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 9249e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 9259e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* 9269e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Compute component-to-pixel lookup tables and dithering kernel 9279e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */ 9289e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org { 9299e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org static GLubyte kernel[16] = { 9309e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 0*16, 8*16, 2*16, 10*16, 9319e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 12*16, 4*16, 14*16, 6*16, 9329e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 3*16, 11*16, 1*16, 9*16, 9339e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 15*16, 7*16, 13*16, 5*16, 9349e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org }; 9359e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org GLint rBits = _mesa_bitcount(rmask); 9369e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org GLint gBits = _mesa_bitcount(gmask); 9379e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org GLint bBits = _mesa_bitcount(bmask); 9389e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org GLint maxBits; 9399e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org GLuint i; 9409e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 9419e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* convert pixel components in [0,_mask] to RGB values in [0,255] */ 9429e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org for (i=0; i<=rmask; i++) 9439e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org v->PixelToR[i] = (unsigned char) ((i * 255) / rmask); 9449e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org for (i=0; i<=gmask; i++) 9459e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org v->PixelToG[i] = (unsigned char) ((i * 255) / gmask); 9469e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org for (i=0; i<=bmask; i++) 9479e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org v->PixelToB[i] = (unsigned char) ((i * 255) / bmask); 9489e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 9499e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* convert RGB values from [0,255] to pixel components */ 9509e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 9519e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org for (i=0;i<256;i++) { 9529e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org GLint r = gamma_adjust(v->RedGamma, i, 255); 9539e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org GLint g = gamma_adjust(v->GreenGamma, i, 255); 9549e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org GLint b = gamma_adjust(v->BlueGamma, i, 255); 9559e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org v->RtoPixel[i] = (r >> (8-rBits)) << v->rshift; 9569e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org v->GtoPixel[i] = (g >> (8-gBits)) << v->gshift; 9579e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org v->BtoPixel[i] = (b >> (8-bBits)) << v->bshift; 9589e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } 9599e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org /* overflow protection */ 960 for (i=256;i<512;i++) { 961 v->RtoPixel[i] = v->RtoPixel[255]; 962 v->GtoPixel[i] = v->GtoPixel[255]; 963 v->BtoPixel[i] = v->BtoPixel[255]; 964 } 965 966 /* setup dithering kernel */ 967 maxBits = rBits; 968 if (gBits > maxBits) maxBits = gBits; 969 if (bBits > maxBits) maxBits = bBits; 970 for (i=0;i<16;i++) { 971 v->Kernel[i] = kernel[i] >> maxBits; 972 } 973 974 v->undithered_pf = PF_Truecolor; 975 v->dithered_pf = (GET_VISUAL_DEPTH(v)<24) ? PF_Dither_True : PF_Truecolor; 976 } 977 978 /* 979 * Now check for TrueColor visuals which we can optimize. 980 */ 981 if ( GET_REDMASK(v) ==0x0000ff 982 && GET_GREENMASK(v)==0x00ff00 983 && GET_BLUEMASK(v) ==0xff0000 984 && CHECK_BYTE_ORDER(v) 985 && v->BitsPerPixel==32 986 && sizeof(GLuint)==4 987 && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) { 988 /* common 32 bpp config used on SGI, Sun */ 989 v->undithered_pf = v->dithered_pf = PF_8A8B8G8R; 990 } 991 else if (GET_REDMASK(v) ==0xff0000 992 && GET_GREENMASK(v)==0x00ff00 993 && GET_BLUEMASK(v) ==0x0000ff 994 && CHECK_BYTE_ORDER(v) 995 && v->BitsPerPixel==32 996 && sizeof(GLuint)==4 997 && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) { 998 /* common 32 bpp config used on Linux, HP, IBM */ 999 if (GET_VISUAL_DEPTH(v)==32) 1000 v->undithered_pf = v->dithered_pf = PF_8A8R8G8B; 1001 else 1002 v->undithered_pf = v->dithered_pf = PF_8R8G8B; 1003 } 1004 else if (GET_REDMASK(v) ==0xff0000 1005 && GET_GREENMASK(v)==0x00ff00 1006 && GET_BLUEMASK(v) ==0x0000ff 1007 && CHECK_BYTE_ORDER(v) 1008 && v->BitsPerPixel==24 1009 && sizeof(GLuint)==4 1010 && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) { 1011 /* common packed 24 bpp config used on Linux */ 1012 v->undithered_pf = v->dithered_pf = PF_8R8G8B24; 1013 } 1014 else if (GET_REDMASK(v) ==0xf800 1015 && GET_GREENMASK(v)==0x07e0 1016 && GET_BLUEMASK(v) ==0x001f 1017 && CHECK_BYTE_ORDER(v) 1018 && v->BitsPerPixel==16 1019 && sizeof(GLushort)==2 1020 && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) { 1021 /* 5-6-5 color weight on common PC VGA boards */ 1022 v->undithered_pf = PF_5R6G5B; 1023 v->dithered_pf = PF_Dither_5R6G5B; 1024 } 1025 else if (GET_REDMASK(v) ==0xe0 1026 && GET_GREENMASK(v)==0x1c 1027 && GET_BLUEMASK(v) ==0x03 1028 && CHECK_FOR_HPCR(v)) { 1029 setup_8bit_hpcr( v ); 1030 } 1031} 1032 1033 1034 1035/** 1036 * Setup RGB rendering for a window with a monochrome visual. 1037 */ 1038static void 1039setup_monochrome( XMesaVisual v, XMesaBuffer b ) 1040{ 1041 (void) b; 1042 v->dithered_pf = v->undithered_pf = PF_1Bit; 1043 /* if black=1 then we must flip pixel values */ 1044 v->bitFlip = (GET_BLACK_PIXEL(v) != 0); 1045} 1046 1047 1048 1049/** 1050 * When a context is bound for the first time, we can finally finish 1051 * initializing the context's visual and buffer information. 1052 * \param v the XMesaVisual to initialize 1053 * \param b the XMesaBuffer to initialize (may be NULL) 1054 * \param rgb_flag TRUE = RGBA mode, FALSE = color index mode 1055 * \param window the window/pixmap we're rendering into 1056 * \param cmap the colormap associated with the window/pixmap 1057 * \return GL_TRUE=success, GL_FALSE=failure 1058 */ 1059static GLboolean 1060initialize_visual_and_buffer(int client, XMesaVisual v, XMesaBuffer b, 1061 GLboolean rgb_flag, XMesaDrawable window, 1062 XMesaColormap cmap) 1063{ 1064 ASSERT(!b || b->xm_visual == v); 1065 1066 /* Save true bits/pixel */ 1067 v->BitsPerPixel = bits_per_pixel(v); 1068 assert(v->BitsPerPixel > 0); 1069 1070 if (rgb_flag == GL_FALSE) { 1071 /* COLOR-INDEXED WINDOW: 1072 * Even if the visual is TrueColor or DirectColor we treat it as 1073 * being color indexed. This is weird but might be useful to someone. 1074 */ 1075 v->dithered_pf = v->undithered_pf = PF_Index; 1076 v->mesa_visual.indexBits = GET_VISUAL_DEPTH(v); 1077 } 1078 else { 1079 /* RGB WINDOW: 1080 * We support RGB rendering into almost any kind of visual. 1081 */ 1082 const int xclass = v->mesa_visual.visualType; 1083 if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) { 1084 setup_truecolor( v, b, cmap ); 1085 } 1086 else if (xclass == GLX_STATIC_GRAY && GET_VISUAL_DEPTH(v) == 1) { 1087 setup_monochrome( v, b ); 1088 } 1089 else if (xclass == GLX_GRAY_SCALE || xclass == GLX_STATIC_GRAY) { 1090 if (!setup_grayscale( client, v, b, cmap )) { 1091 return GL_FALSE; 1092 } 1093 } 1094 else if ((xclass == GLX_PSEUDO_COLOR || xclass == GLX_STATIC_COLOR) 1095 && GET_VISUAL_DEPTH(v)>=4 && GET_VISUAL_DEPTH(v)<=16) { 1096 if (!setup_dithered_color( client, v, b, cmap )) { 1097 return GL_FALSE; 1098 } 1099 } 1100 else { 1101 _mesa_warning(NULL, "XMesa: RGB mode rendering not supported in given visual.\n"); 1102 return GL_FALSE; 1103 } 1104 v->mesa_visual.indexBits = 0; 1105 1106 if (_mesa_getenv("MESA_NO_DITHER")) { 1107 v->dithered_pf = v->undithered_pf; 1108 } 1109 } 1110 1111 1112 /* 1113 * If MESA_INFO env var is set print out some debugging info 1114 * which can help Brian figure out what's going on when a user 1115 * reports bugs. 1116 */ 1117 if (_mesa_getenv("MESA_INFO")) { 1118 _mesa_printf("X/Mesa visual = %p\n", (void *) v); 1119 _mesa_printf("X/Mesa dithered pf = %u\n", v->dithered_pf); 1120 _mesa_printf("X/Mesa undithered pf = %u\n", v->undithered_pf); 1121 _mesa_printf("X/Mesa level = %d\n", v->mesa_visual.level); 1122 _mesa_printf("X/Mesa depth = %d\n", GET_VISUAL_DEPTH(v)); 1123 _mesa_printf("X/Mesa bits per pixel = %d\n", v->BitsPerPixel); 1124 } 1125 1126 if (b && window) { 1127 /* Do window-specific initializations */ 1128 1129 /* these should have been set in create_xmesa_buffer */ 1130 ASSERT(b->frontxrb->drawable == window); 1131 ASSERT(b->frontxrb->pixmap == (XMesaPixmap) window); 1132 1133 /* Setup for single/double buffering */ 1134 if (v->mesa_visual.doubleBufferMode) { 1135 /* Double buffered */ 1136 b->shm = check_for_xshm( v->display ); 1137 } 1138 1139 /* X11 graphics contexts */ 1140#ifdef XFree86Server 1141 b->gc = CreateScratchGC(v->display, window->depth); 1142#else 1143 b->gc = XCreateGC( v->display, window, 0, NULL ); 1144#endif 1145 XMesaSetFunction( v->display, b->gc, GXcopy ); 1146 1147 /* cleargc - for glClear() */ 1148#ifdef XFree86Server 1149 b->cleargc = CreateScratchGC(v->display, window->depth); 1150#else 1151 b->cleargc = XCreateGC( v->display, window, 0, NULL ); 1152#endif 1153 XMesaSetFunction( v->display, b->cleargc, GXcopy ); 1154 1155 /* 1156 * Don't generate Graphics Expose/NoExpose events in swapbuffers(). 1157 * Patch contributed by Michael Pichler May 15, 1995. 1158 */ 1159#ifdef XFree86Server 1160 b->swapgc = CreateScratchGC(v->display, window->depth); 1161 { 1162 CARD32 v[1]; 1163 v[0] = FALSE; 1164 dixChangeGC(NullClient, b->swapgc, GCGraphicsExposures, v, NULL); 1165 } 1166#else 1167 { 1168 XGCValues gcvalues; 1169 gcvalues.graphics_exposures = False; 1170 b->swapgc = XCreateGC(v->display, window, 1171 GCGraphicsExposures, &gcvalues); 1172 } 1173#endif 1174 XMesaSetFunction( v->display, b->swapgc, GXcopy ); 1175 /* 1176 * Set fill style and tile pixmap once for all for HPCR stuff 1177 * (instead of doing it each time in clear_color_HPCR_pixmap()) 1178 * Initialize whole stuff 1179 * Patch contributed by Jacques Leroy March 8, 1998. 1180 */ 1181 if (v->hpcr_clear_flag && b->backxrb && b->backxrb->pixmap) { 1182 int i; 1183 for (i = 0; i < 16; i++) { 1184 XMesaPutPixel(v->hpcr_clear_ximage, i, 0, 0); 1185 XMesaPutPixel(v->hpcr_clear_ximage, i, 1, 0); 1186 } 1187 XMesaPutImage(b->display, (XMesaDrawable) v->hpcr_clear_pixmap, 1188 b->cleargc, v->hpcr_clear_ximage, 0, 0, 0, 0, 16, 2); 1189 XMesaSetFillStyle( v->display, b->cleargc, FillTiled); 1190 XMesaSetTile( v->display, b->cleargc, v->hpcr_clear_pixmap ); 1191 } 1192 1193 /* Initialize the row buffer XImage for use in write_color_span() */ 1194#ifdef XFree86Server 1195 b->rowimage = XMesaCreateImage(GET_VISUAL_DEPTH(v), MAX_WIDTH, 1, 1196 (char *)MALLOC(MAX_WIDTH*4)); 1197#else 1198 b->rowimage = XCreateImage( v->display, 1199 v->visinfo->visual, 1200 v->visinfo->depth, 1201 ZPixmap, 0, /*format, offset*/ 1202 (char*) MALLOC(MAX_WIDTH*4), /*data*/ 1203 MAX_WIDTH, 1, /*width, height*/ 1204 32, /*bitmap_pad*/ 1205 0 /*bytes_per_line*/ ); 1206#endif 1207 if (!b->rowimage) 1208 return GL_FALSE; 1209 } 1210 1211 return GL_TRUE; 1212} 1213 1214 1215 1216/* 1217 * Convert an RGBA color to a pixel value. 1218 */ 1219unsigned long 1220xmesa_color_to_pixel(GLcontext *ctx, 1221 GLubyte r, GLubyte g, GLubyte b, GLubyte a, 1222 GLuint pixelFormat) 1223{ 1224 XMesaContext xmesa = XMESA_CONTEXT(ctx); 1225 switch (pixelFormat) { 1226 case PF_Index: 1227 return 0; 1228 case PF_Truecolor: 1229 { 1230 unsigned long p; 1231 PACK_TRUECOLOR( p, r, g, b ); 1232 return p; 1233 } 1234 case PF_8A8B8G8R: 1235 return PACK_8A8B8G8R( r, g, b, a ); 1236 case PF_8A8R8G8B: 1237 return PACK_8A8R8G8B( r, g, b, a ); 1238 case PF_8R8G8B: 1239 /* fall through */ 1240 case PF_8R8G8B24: 1241 return PACK_8R8G8B( r, g, b ); 1242 case PF_5R6G5B: 1243 return PACK_5R6G5B( r, g, b ); 1244 case PF_Dither: 1245 { 1246 DITHER_SETUP; 1247 return DITHER( 1, 0, r, g, b ); 1248 } 1249 case PF_1Bit: 1250 /* 382 = (3*255)/2 */ 1251 return ((r+g+b) > 382) ^ xmesa->xm_visual->bitFlip; 1252 case PF_HPCR: 1253 return DITHER_HPCR(1, 1, r, g, b); 1254 case PF_Lookup: 1255 { 1256 LOOKUP_SETUP; 1257 return LOOKUP( r, g, b ); 1258 } 1259 case PF_Grayscale: 1260 return GRAY_RGB( r, g, b ); 1261 case PF_Dither_True: 1262 /* fall through */ 1263 case PF_Dither_5R6G5B: 1264 { 1265 unsigned long p; 1266 PACK_TRUEDITHER(p, 1, 0, r, g, b); 1267 return p; 1268 } 1269 default: 1270 _mesa_problem(ctx, "Bad pixel format in xmesa_color_to_pixel"); 1271 } 1272 return 0; 1273} 1274 1275 1276#define NUM_VISUAL_TYPES 6 1277 1278/** 1279 * Convert an X visual type to a GLX visual type. 1280 * 1281 * \param visualType X visual type (i.e., \c TrueColor, \c StaticGray, etc.) 1282 * to be converted. 1283 * \return If \c visualType is a valid X visual type, a GLX visual type will 1284 * be returned. Otherwise \c GLX_NONE will be returned. 1285 * 1286 * \note 1287 * This code was lifted directly from lib/GL/glx/glcontextmodes.c in the 1288 * DRI CVS tree. 1289 */ 1290static GLint 1291xmesa_convert_from_x_visual_type( int visualType ) 1292{ 1293 static const int glx_visual_types[ NUM_VISUAL_TYPES ] = { 1294 GLX_STATIC_GRAY, GLX_GRAY_SCALE, 1295 GLX_STATIC_COLOR, GLX_PSEUDO_COLOR, 1296 GLX_TRUE_COLOR, GLX_DIRECT_COLOR 1297 }; 1298 1299 return ( (unsigned) visualType < NUM_VISUAL_TYPES ) 1300 ? glx_visual_types[ visualType ] : GLX_NONE; 1301} 1302 1303 1304/**********************************************************************/ 1305/***** Public Functions *****/ 1306/**********************************************************************/ 1307 1308 1309/* 1310 * Create a new X/Mesa visual. 1311 * Input: display - X11 display 1312 * visinfo - an XVisualInfo pointer 1313 * rgb_flag - GL_TRUE = RGB mode, 1314 * GL_FALSE = color index mode 1315 * alpha_flag - alpha buffer requested? 1316 * db_flag - GL_TRUE = double-buffered, 1317 * GL_FALSE = single buffered 1318 * stereo_flag - stereo visual? 1319 * ximage_flag - GL_TRUE = use an XImage for back buffer, 1320 * GL_FALSE = use an off-screen pixmap for back buffer 1321 * depth_size - requested bits/depth values, or zero 1322 * stencil_size - requested bits/stencil values, or zero 1323 * accum_red_size - requested bits/red accum values, or zero 1324 * accum_green_size - requested bits/green accum values, or zero 1325 * accum_blue_size - requested bits/blue accum values, or zero 1326 * accum_alpha_size - requested bits/alpha accum values, or zero 1327 * num_samples - number of samples/pixel if multisampling, or zero 1328 * level - visual level, usually 0 1329 * visualCaveat - ala the GLX extension, usually GLX_NONE 1330 * Return; a new XMesaVisual or 0 if error. 1331 */ 1332XMesaVisual XMesaCreateVisual( XMesaDisplay *display, 1333 XMesaVisualInfo visinfo, 1334 GLboolean rgb_flag, 1335 GLboolean alpha_flag, 1336 GLboolean db_flag, 1337 GLboolean stereo_flag, 1338 GLboolean ximage_flag, 1339 GLint depth_size, 1340 GLint stencil_size, 1341 GLint accum_red_size, 1342 GLint accum_green_size, 1343 GLint accum_blue_size, 1344 GLint accum_alpha_size, 1345 GLint num_samples, 1346 GLint level, 1347 GLint visualCaveat ) 1348{ 1349 char *gamma; 1350 XMesaVisual v; 1351 GLint red_bits, green_bits, blue_bits, alpha_bits; 1352 1353#ifndef XFree86Server 1354 /* For debugging only */ 1355 if (_mesa_getenv("MESA_XSYNC")) { 1356 /* This makes debugging X easier. 1357 * In your debugger, set a breakpoint on _XError to stop when an 1358 * X protocol error is generated. 1359 */ 1360 XSynchronize( display, 1 ); 1361 } 1362#endif 1363 1364 v = (XMesaVisual) CALLOC_STRUCT(xmesa_visual); 1365 if (!v) { 1366 return NULL; 1367 } 1368 1369 /* 1370 * In the X server, NULL is passed in for the display. It will have 1371 * to be set before using this visual. See XMesaSetVisualDisplay() 1372 * below. 1373 */ 1374 v->display = display; 1375 1376 /* Save a copy of the XVisualInfo struct because the user may X_mesa_free() 1377 * the struct but we may need some of the information contained in it 1378 * at a later time. 1379 */ 1380#ifndef XFree86Server 1381 v->visinfo = (XVisualInfo *) MALLOC(sizeof(*visinfo)); 1382 if(!v->visinfo) { 1383 _mesa_free(v); 1384 return NULL; 1385 } 1386 MEMCPY(v->visinfo, visinfo, sizeof(*visinfo)); 1387#endif 1388 1389 /* check for MESA_GAMMA environment variable */ 1390 gamma = _mesa_getenv("MESA_GAMMA"); 1391 if (gamma) { 1392 v->RedGamma = v->GreenGamma = v->BlueGamma = 0.0; 1393 sscanf( gamma, "%f %f %f", &v->RedGamma, &v->GreenGamma, &v->BlueGamma ); 1394 if (v->RedGamma<=0.0) v->RedGamma = 1.0; 1395 if (v->GreenGamma<=0.0) v->GreenGamma = v->RedGamma; 1396 if (v->BlueGamma<=0.0) v->BlueGamma = v->RedGamma; 1397 } 1398 else { 1399 v->RedGamma = v->GreenGamma = v->BlueGamma = 1.0; 1400 } 1401 1402 v->ximage_flag = ximage_flag; 1403 1404#ifdef XFree86Server 1405 /* We could calculate these values by ourselves. nplanes is either the sum 1406 * of the red, green, and blue bits or the number index bits. 1407 * ColormapEntries is either (1U << index_bits) or 1408 * (1U << max(redBits, greenBits, blueBits)). 1409 */ 1410 assert(visinfo->nplanes > 0); 1411 v->nplanes = visinfo->nplanes; 1412 v->ColormapEntries = visinfo->ColormapEntries; 1413 1414 v->mesa_visual.redMask = visinfo->redMask; 1415 v->mesa_visual.greenMask = visinfo->greenMask; 1416 v->mesa_visual.blueMask = visinfo->blueMask; 1417 v->mesa_visual.visualID = visinfo->vid; 1418 v->mesa_visual.screen = 0; /* FIXME: What should be done here? */ 1419#else 1420 v->mesa_visual.redMask = visinfo->red_mask; 1421 v->mesa_visual.greenMask = visinfo->green_mask; 1422 v->mesa_visual.blueMask = visinfo->blue_mask; 1423 v->mesa_visual.visualID = visinfo->visualid; 1424 v->mesa_visual.screen = visinfo->screen; 1425#endif 1426 1427#if defined(XFree86Server) || !(defined(__cplusplus) || defined(c_plusplus)) 1428 v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->class); 1429#else 1430 v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->c_class); 1431#endif 1432 1433 v->mesa_visual.visualRating = visualCaveat; 1434 1435 (void) initialize_visual_and_buffer( 0, v, NULL, rgb_flag, 0, 0 ); 1436 1437 { 1438 const int xclass = v->mesa_visual.visualType; 1439 if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) { 1440 red_bits = _mesa_bitcount(GET_REDMASK(v)); 1441 green_bits = _mesa_bitcount(GET_GREENMASK(v)); 1442 blue_bits = _mesa_bitcount(GET_BLUEMASK(v)); 1443 alpha_bits = 0; 1444 } 1445 else { 1446 /* this is an approximation */ 1447 int depth; 1448 depth = GET_VISUAL_DEPTH(v); 1449 red_bits = depth / 3; 1450 depth -= red_bits; 1451 green_bits = depth / 2; 1452 depth -= green_bits; 1453 blue_bits = depth; 1454 alpha_bits = 0; 1455 assert( red_bits + green_bits + blue_bits == GET_VISUAL_DEPTH(v) ); 1456 } 1457 } 1458 1459 if (alpha_flag && alpha_bits == 0) 1460 alpha_bits = 8; 1461 1462 _mesa_initialize_visual( &v->mesa_visual, 1463 rgb_flag, db_flag, stereo_flag, 1464 red_bits, green_bits, 1465 blue_bits, alpha_bits, 1466 v->mesa_visual.indexBits, 1467 depth_size, 1468 stencil_size, 1469 accum_red_size, accum_green_size, 1470 accum_blue_size, accum_alpha_size, 1471 0 ); 1472 1473 /* XXX minor hack */ 1474 v->mesa_visual.level = level; 1475 return v; 1476} 1477 1478 1479void XMesaSetVisualDisplay( XMesaDisplay *dpy, XMesaVisual v ) 1480{ 1481 v->display = dpy; 1482} 1483 1484 1485void XMesaDestroyVisual( XMesaVisual v ) 1486{ 1487#ifndef XFree86Server 1488 _mesa_free(v->visinfo); 1489#endif 1490 _mesa_free(v); 1491} 1492 1493 1494 1495/** 1496 * Create a new XMesaContext. 1497 * \param v the XMesaVisual 1498 * \param share_list another XMesaContext with which to share display 1499 * lists or NULL if no sharing is wanted. 1500 * \return an XMesaContext or NULL if error. 1501 */ 1502XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) 1503{ 1504 static GLboolean firstTime = GL_TRUE; 1505 XMesaContext c; 1506 GLcontext *mesaCtx; 1507 struct dd_function_table functions; 1508 TNLcontext *tnl; 1509 1510 if (firstTime) { 1511 _glthread_INIT_MUTEX(_xmesa_lock); 1512 firstTime = GL_FALSE; 1513 } 1514 1515 /* Note: the XMesaContext contains a Mesa GLcontext struct (inheritance) */ 1516 c = (XMesaContext) CALLOC_STRUCT(xmesa_context); 1517 if (!c) 1518 return NULL; 1519 1520 mesaCtx = &(c->mesa); 1521 1522 /* initialize with default driver functions, then plug in XMesa funcs */ 1523 _mesa_init_driver_functions(&functions); 1524 xmesa_init_driver_functions(v, &functions); 1525 if (!_mesa_initialize_context(mesaCtx, &v->mesa_visual, 1526 share_list ? &(share_list->mesa) : (GLcontext *) NULL, 1527 &functions, (void *) c)) { 1528 _mesa_free(c); 1529 return NULL; 1530 } 1531 1532 _mesa_enable_sw_extensions(mesaCtx); 1533 _mesa_enable_1_3_extensions(mesaCtx); 1534 _mesa_enable_1_4_extensions(mesaCtx); 1535 _mesa_enable_1_5_extensions(mesaCtx); 1536 _mesa_enable_2_0_extensions(mesaCtx); 1537#if ENABLE_EXT_texure_compression_s3tc 1538 if (c->Mesa_DXTn) { 1539 _mesa_enable_extension(mesaCtx, "GL_EXT_texture_compression_s3tc"); 1540 _mesa_enable_extension(mesaCtx, "GL_S3_s3tc"); 1541 } 1542 _mesa_enable_extension(mesaCtx, "GL_3DFX_texture_compression_FXT1"); 1543#endif 1544#if ENABLE_EXT_timer_query 1545 _mesa_enable_extension(mesaCtx, "GL_EXT_timer_query"); 1546#endif 1547 1548 /* finish up xmesa context initializations */ 1549 c->swapbytes = CHECK_BYTE_ORDER(v) ? GL_FALSE : GL_TRUE; 1550 c->xm_visual = v; 1551 c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */ 1552 c->display = v->display; 1553 c->pixelformat = v->dithered_pf; /* Dithering is enabled by default */ 1554 1555 /* Initialize the software rasterizer and helper modules. 1556 */ 1557 if (!_swrast_CreateContext( mesaCtx ) || 1558 !_vbo_CreateContext( mesaCtx ) || 1559 !_tnl_CreateContext( mesaCtx ) || 1560 !_swsetup_CreateContext( mesaCtx )) { 1561 _mesa_free_context_data(&c->mesa); 1562 _mesa_free(c); 1563 return NULL; 1564 } 1565 1566 /* tnl setup */ 1567 tnl = TNL_CONTEXT(mesaCtx); 1568 tnl->Driver.RunPipeline = _tnl_run_pipeline; 1569 /* swrast setup */ 1570 xmesa_register_swrast_functions( mesaCtx ); 1571 _swsetup_Wakeup(mesaCtx); 1572 1573 return c; 1574} 1575 1576 1577 1578void XMesaDestroyContext( XMesaContext c ) 1579{ 1580 GLcontext *mesaCtx = &c->mesa; 1581#ifdef FX 1582 XMesaBuffer xmbuf = XMESA_BUFFER(mesaCtx->DrawBuffer); 1583 1584 if (xmbuf && xmbuf->FXctx) 1585 fxMesaDestroyContext(xmbuf->FXctx); 1586#endif 1587 _swsetup_DestroyContext( mesaCtx ); 1588 _swrast_DestroyContext( mesaCtx ); 1589 _tnl_DestroyContext( mesaCtx ); 1590 _vbo_DestroyContext( mesaCtx ); 1591 _mesa_free_context_data( mesaCtx ); 1592 _mesa_free( c ); 1593} 1594 1595 1596 1597/** 1598 * Private function for creating an XMesaBuffer which corresponds to an 1599 * X window or pixmap. 1600 * \param v the window's XMesaVisual 1601 * \param w the window we're wrapping 1602 * \param c context used to initialize the buffer if 3Dfx mode in use. 1603 * \return new XMesaBuffer or NULL if error 1604 */ 1605XMesaBuffer 1606XMesaCreateWindowBuffer2(XMesaVisual v, XMesaWindow w, XMesaContext c) 1607{ 1608#ifndef XFree86Server 1609 XWindowAttributes attr; 1610#endif 1611#ifdef FX 1612 char *fxEnvVar; 1613#endif 1614 int client = 0; 1615 XMesaBuffer b; 1616 XMesaColormap cmap; 1617 1618 assert(v); 1619 assert(w); 1620 (void) c; 1621 1622 /* Check that window depth matches visual depth */ 1623#ifdef XFree86Server 1624 client = CLIENT_ID(((XMesaDrawable)w)->id); 1625 1626 if (GET_VISUAL_DEPTH(v) != ((XMesaDrawable)w)->depth) { 1627 _mesa_warning(NULL, "XMesaCreateWindowBuffer: depth mismatch between visual (%d) and window (%d)!\n", 1628 GET_VISUAL_DEPTH(v), ((XMesaDrawable) w)->depth); 1629 return NULL; 1630 } 1631#else 1632 XGetWindowAttributes( v->display, w, &attr ); 1633 1634 if (GET_VISUAL_DEPTH(v) != attr.depth) { 1635 _mesa_warning(NULL, "XMesaCreateWindowBuffer: depth mismatch between visual (%d) and window (%d)!\n", 1636 GET_VISUAL_DEPTH(v), attr.depth); 1637 return NULL; 1638 } 1639#endif 1640 1641 /* Find colormap */ 1642#ifdef XFree86Server 1643 cmap = (ColormapPtr)LookupIDByType(wColormap(w), RT_COLORMAP); 1644#else 1645 if (attr.colormap) { 1646 cmap = attr.colormap; 1647 } 1648 else { 1649 _mesa_warning(NULL, "Window %u has no colormap!\n", (unsigned int) w); 1650 /* this is weird, a window w/out a colormap!? */ 1651 /* OK, let's just allocate a new one and hope for the best */ 1652 cmap = XCreateColormap(v->display, w, attr.visual, AllocNone); 1653 } 1654#endif 1655 1656 b = create_xmesa_buffer((XMesaDrawable) w, WINDOW, v, cmap); 1657 if (!b) 1658 return NULL; 1659 1660 if (!initialize_visual_and_buffer( client, v, b, v->mesa_visual.rgbMode, 1661 (XMesaDrawable) w, cmap )) { 1662 free_xmesa_buffer(client, b); 1663 return NULL; 1664 } 1665 1666#ifdef FX 1667 fxEnvVar = _mesa_getenv("MESA_GLX_FX"); 1668 if (fxEnvVar) { 1669 if (fxEnvVar[0]!='d') { 1670 int attribs[100]; 1671 int numAttribs = 0; 1672 int hw; 1673 if (v->mesa_visual.depthBits > 0) { 1674 attribs[numAttribs++] = FXMESA_DEPTH_SIZE; 1675 attribs[numAttribs++] = v->mesa_visual.depthBits; 1676 } 1677 if (v->mesa_visual.doubleBufferMode) { 1678 attribs[numAttribs++] = FXMESA_DOUBLEBUFFER; 1679 } 1680 if (v->mesa_visual.accumRedBits > 0) { 1681 attribs[numAttribs++] = FXMESA_ACCUM_SIZE; 1682 attribs[numAttribs++] = v->mesa_visual.accumRedBits; 1683 } 1684 if (v->mesa_visual.stencilBits > 0) { 1685 attribs[numAttribs++] = FXMESA_STENCIL_SIZE; 1686 attribs[numAttribs++] = v->mesa_visual.stencilBits; 1687 } 1688 if (v->mesa_visual.alphaBits > 0) { 1689 attribs[numAttribs++] = FXMESA_ALPHA_SIZE; 1690 attribs[numAttribs++] = v->mesa_visual.alphaBits; 1691 } 1692 if (1) { 1693 attribs[numAttribs++] = FXMESA_SHARE_CONTEXT; 1694 attribs[numAttribs++] = (int) &(c->mesa); 1695 } 1696 attribs[numAttribs++] = FXMESA_NONE; 1697 1698 /* [dBorca] we should take an envvar for `fxMesaSelectCurrentBoard'!!! */ 1699 hw = fxMesaSelectCurrentBoard(0); 1700 1701 /* if these fail, there's a new bug somewhere */ 1702 ASSERT(b->mesa_buffer.Width > 0); 1703 ASSERT(b->mesa_buffer.Height > 0); 1704 1705 if ((hw == GR_SSTTYPE_VOODOO) || (hw == GR_SSTTYPE_Voodoo2)) { 1706 b->FXctx = fxMesaCreateBestContext(0, b->mesa_buffer.Width, 1707 b->mesa_buffer.Height, attribs); 1708 if ((v->undithered_pf!=PF_Index) && (b->backxrb->ximage)) { 1709 b->FXisHackUsable = b->FXctx ? GL_TRUE : GL_FALSE; 1710 if (b->FXctx && (fxEnvVar[0]=='w' || fxEnvVar[0]=='W')) { 1711 b->FXwindowHack = GL_TRUE; 1712 FX_grSstControl(GR_CONTROL_DEACTIVATE); 1713 } 1714 else { 1715 b->FXwindowHack = GL_FALSE; 1716 } 1717 } 1718 } 1719 else { 1720 if (fxEnvVar[0]=='w' || fxEnvVar[0]=='W') 1721 b->FXctx = fxMesaCreateContext(w, GR_RESOLUTION_NONE, 1722 GR_REFRESH_75Hz, attribs); 1723 else 1724 b->FXctx = fxMesaCreateBestContext(0, b->mesa_buffer.Width, 1725 b->mesa_buffer.Height, attribs); 1726 b->FXisHackUsable = GL_FALSE; 1727 b->FXwindowHack = GL_FALSE; 1728 } 1729 /* 1730 fprintf(stderr, 1731 "voodoo %d, wid %d height %d hack: usable %d active %d\n", 1732 hw, b->mesa_buffer.Width, b->mesa_buffer.Height, 1733 b->FXisHackUsable, b->FXwindowHack); 1734 */ 1735 } 1736 } 1737 else { 1738 _mesa_warning(NULL, "WARNING: This Mesa Library includes the Glide driver but\n"); 1739 _mesa_warning(NULL, " you have not defined the MESA_GLX_FX env. var.\n"); 1740 _mesa_warning(NULL, " (check the README.3DFX file for more information).\n\n"); 1741 _mesa_warning(NULL, " you can disable this message with a 'export MESA_GLX_FX=disable'.\n"); 1742 } 1743#endif 1744 1745 return b; 1746} 1747 1748 1749XMesaBuffer 1750XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w) 1751{ 1752 return XMesaCreateWindowBuffer2( v, w, NULL ); 1753} 1754 1755 1756/** 1757 * Create a new XMesaBuffer from an X pixmap. 1758 * 1759 * \param v the XMesaVisual 1760 * \param p the pixmap 1761 * \param cmap the colormap, may be 0 if using a \c GLX_TRUE_COLOR or 1762 * \c GLX_DIRECT_COLOR visual for the pixmap 1763 * \returns new XMesaBuffer or NULL if error 1764 */ 1765XMesaBuffer 1766XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p, XMesaColormap cmap) 1767{ 1768 int client = 0; 1769 XMesaBuffer b; 1770 1771 assert(v); 1772 1773 b = create_xmesa_buffer((XMesaDrawable) p, PIXMAP, v, cmap); 1774 if (!b) 1775 return NULL; 1776 1777#ifdef XFree86Server 1778 client = CLIENT_ID(((XMesaDrawable)p)->id); 1779#endif 1780 1781 if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode, 1782 (XMesaDrawable) p, cmap)) { 1783 free_xmesa_buffer(client, b); 1784 return NULL; 1785 } 1786 1787 return b; 1788} 1789 1790 1791 1792XMesaBuffer 1793XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap, 1794 unsigned int width, unsigned int height) 1795{ 1796#ifdef XFree86Server 1797 return 0; 1798#else 1799 int client = 0; 1800 XMesaWindow root; 1801 XMesaDrawable drawable; /* X Pixmap Drawable */ 1802 XMesaBuffer b; 1803 1804 /* allocate pixmap for front buffer */ 1805 root = RootWindow( v->display, v->visinfo->screen ); 1806 drawable = XCreatePixmap(v->display, root, width, height, 1807 v->visinfo->depth); 1808 if (!drawable) 1809 return NULL; 1810 1811 b = create_xmesa_buffer(drawable, PBUFFER, v, cmap); 1812 if (!b) 1813 return NULL; 1814 1815 if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode, 1816 drawable, cmap)) { 1817 free_xmesa_buffer(client, b); 1818 return NULL; 1819 } 1820 1821 return b; 1822#endif 1823} 1824 1825 1826 1827/* 1828 * Deallocate an XMesaBuffer structure and all related info. 1829 */ 1830void XMesaDestroyBuffer( XMesaBuffer b ) 1831{ 1832 int client = 0; 1833 1834#ifdef XFree86Server 1835 if (b->frontxrb->drawable) 1836 client = CLIENT_ID(b->frontxrb->drawable->id); 1837#endif 1838 1839 if (b->gc) XMesaFreeGC( b->xm_visual->display, b->gc ); 1840 if (b->cleargc) XMesaFreeGC( b->xm_visual->display, b->cleargc ); 1841 if (b->swapgc) XMesaFreeGC( b->xm_visual->display, b->swapgc ); 1842 1843 if (b->xm_visual->mesa_visual.doubleBufferMode) 1844 { 1845 if (b->backxrb->ximage) { 1846#if defined(USE_XSHM) && !defined(XFree86Server) 1847 if (b->shm) { 1848 XShmDetach( b->xm_visual->display, &b->shminfo ); 1849 XDestroyImage( b->backxrb->ximage ); 1850 shmdt( b->shminfo.shmaddr ); 1851 } 1852 else 1853#endif 1854 XMesaDestroyImage( b->backxrb->ximage ); 1855 } 1856 if (b->backxrb->pixmap) { 1857 XMesaFreePixmap( b->xm_visual->display, b->backxrb->pixmap ); 1858 if (b->xm_visual->hpcr_clear_flag) { 1859 XMesaFreePixmap( b->xm_visual->display, 1860 b->xm_visual->hpcr_clear_pixmap ); 1861 XMesaDestroyImage( b->xm_visual->hpcr_clear_ximage ); 1862 } 1863 } 1864 } 1865 if (b->rowimage) { 1866 _mesa_free( b->rowimage->data ); 1867 b->rowimage->data = NULL; 1868 XMesaDestroyImage( b->rowimage ); 1869 } 1870 1871 free_xmesa_buffer(client, b); 1872} 1873 1874 1875/** 1876 * Query the current window size and update the corresponding GLframebuffer 1877 * and all attached renderbuffers. 1878 * Called when: 1879 * 1. the first time a buffer is bound to a context. 1880 * 2. from glViewport to poll for window size changes 1881 * 3. from the XMesaResizeBuffers() API function. 1882 */ 1883void 1884xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer) 1885{ 1886 GLuint width, height; 1887 xmesa_get_window_size(xmctx->display, drawBuffer, &width, &height); 1888 if (drawBuffer->mesa_buffer.Width != width || 1889 drawBuffer->mesa_buffer.Height != height) { 1890 _mesa_resize_framebuffer(&(xmctx->mesa), 1891 &(drawBuffer->mesa_buffer), width, height); 1892 } 1893 drawBuffer->mesa_buffer.Initialized = GL_TRUE; /* XXX TEMPORARY? */ 1894} 1895 1896 1897/* 1898 * Bind buffer b to context c and make c the current rendering context. 1899 */ 1900GLboolean XMesaMakeCurrent( XMesaContext c, XMesaBuffer b ) 1901{ 1902 return XMesaMakeCurrent2( c, b, b ); 1903} 1904 1905 1906/* 1907 * Bind buffer b to context c and make c the current rendering context. 1908 */ 1909GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer, 1910 XMesaBuffer readBuffer ) 1911{ 1912 if (c) { 1913 if (!drawBuffer || !readBuffer) 1914 return GL_FALSE; /* must specify buffers! */ 1915 1916#ifdef FX 1917 if (drawBuffer->FXctx) { 1918 fxMesaMakeCurrent(drawBuffer->FXctx); 1919 1920 c->xm_buffer = drawBuffer; 1921 1922 return GL_TRUE; 1923 } 1924#endif 1925 if (&(c->mesa) == _mesa_get_current_context() 1926 && c->mesa.DrawBuffer == &drawBuffer->mesa_buffer 1927 && c->mesa.ReadBuffer == &readBuffer->mesa_buffer 1928 && XMESA_BUFFER(c->mesa.DrawBuffer)->wasCurrent) { 1929 /* same context and buffer, do nothing */ 1930 return GL_TRUE; 1931 } 1932 1933 c->xm_buffer = drawBuffer; 1934 1935 /* Call this periodically to detect when the user has begun using 1936 * GL rendering from multiple threads. 1937 */ 1938 _glapi_check_multithread(); 1939 1940 xmesa_check_and_update_buffer_size(c, drawBuffer); 1941 if (readBuffer != drawBuffer) 1942 xmesa_check_and_update_buffer_size(c, readBuffer); 1943 1944 _mesa_make_current(&(c->mesa), 1945 &drawBuffer->mesa_buffer, 1946 &readBuffer->mesa_buffer); 1947 1948 if (c->xm_visual->mesa_visual.rgbMode) { 1949 /* 1950 * Must recompute and set these pixel values because colormap 1951 * can be different for different windows. 1952 */ 1953 c->clearpixel = xmesa_color_to_pixel( &c->mesa, 1954 c->clearcolor[0], 1955 c->clearcolor[1], 1956 c->clearcolor[2], 1957 c->clearcolor[3], 1958 c->xm_visual->undithered_pf); 1959 XMesaSetForeground(c->display, drawBuffer->cleargc, c->clearpixel); 1960 } 1961 1962 /* Solution to Stephane Rehel's problem with glXReleaseBuffersMESA(): */ 1963 drawBuffer->wasCurrent = GL_TRUE; 1964 } 1965 else { 1966 /* Detach */ 1967 _mesa_make_current( NULL, NULL, NULL ); 1968 } 1969 return GL_TRUE; 1970} 1971 1972 1973/* 1974 * Unbind the context c from its buffer. 1975 */ 1976GLboolean XMesaUnbindContext( XMesaContext c ) 1977{ 1978 /* A no-op for XFree86 integration purposes */ 1979 return GL_TRUE; 1980} 1981 1982 1983XMesaContext XMesaGetCurrentContext( void ) 1984{ 1985 GET_CURRENT_CONTEXT(ctx); 1986 if (ctx) { 1987 XMesaContext xmesa = XMESA_CONTEXT(ctx); 1988 return xmesa; 1989 } 1990 else { 1991 return 0; 1992 } 1993} 1994 1995 1996XMesaBuffer XMesaGetCurrentBuffer( void ) 1997{ 1998 GET_CURRENT_CONTEXT(ctx); 1999 if (ctx) { 2000 XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); 2001 return xmbuf; 2002 } 2003 else { 2004 return 0; 2005 } 2006} 2007 2008 2009/* New in Mesa 3.1 */ 2010XMesaBuffer XMesaGetCurrentReadBuffer( void ) 2011{ 2012 GET_CURRENT_CONTEXT(ctx); 2013 if (ctx) { 2014 return XMESA_BUFFER(ctx->ReadBuffer); 2015 } 2016 else { 2017 return 0; 2018 } 2019} 2020 2021 2022GLboolean XMesaForceCurrent(XMesaContext c) 2023{ 2024 if (c) { 2025 if (&(c->mesa) != _mesa_get_current_context()) { 2026 _mesa_make_current(&c->mesa, c->mesa.DrawBuffer, c->mesa.ReadBuffer); 2027 } 2028 } 2029 else { 2030 _mesa_make_current(NULL, NULL, NULL); 2031 } 2032 return GL_TRUE; 2033} 2034 2035 2036GLboolean XMesaLoseCurrent(XMesaContext c) 2037{ 2038 (void) c; 2039 _mesa_make_current(NULL, NULL, NULL); 2040 return GL_TRUE; 2041} 2042 2043 2044/* 2045 * Switch 3Dfx support hack between window and full-screen mode. 2046 */ 2047GLboolean XMesaSetFXmode( GLint mode ) 2048{ 2049#ifdef FX 2050 const char *fx = _mesa_getenv("MESA_GLX_FX"); 2051 if (fx && fx[0] != 'd') { 2052 GET_CURRENT_CONTEXT(ctx); 2053 GrHwConfiguration hw; 2054 if (!FX_grSstQueryHardware(&hw)) { 2055 /*fprintf(stderr, "!grSstQueryHardware\n");*/ 2056 return GL_FALSE; 2057 } 2058 if (hw.num_sst < 1) { 2059 /*fprintf(stderr, "hw.num_sst < 1\n");*/ 2060 return GL_FALSE; 2061 } 2062 if (ctx) { 2063 /* [dBorca] Hack alert: 2064 * oh, this is sooo wrong: ctx above is 2065 * really an fxMesaContext, not an XMesaContext 2066 */ 2067 XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); 2068 if (mode == XMESA_FX_WINDOW) { 2069 if (xmbuf->FXisHackUsable) { 2070 FX_grSstControl(GR_CONTROL_DEACTIVATE); 2071 xmbuf->FXwindowHack = GL_TRUE; 2072 return GL_TRUE; 2073 } 2074 } 2075 else if (mode == XMESA_FX_FULLSCREEN) { 2076 FX_grSstControl(GR_CONTROL_ACTIVATE); 2077 xmbuf->FXwindowHack = GL_FALSE; 2078 return GL_TRUE; 2079 } 2080 else { 2081 /* Error: Bad mode value */ 2082 } 2083 } 2084 } 2085 /*fprintf(stderr, "fallthrough\n");*/ 2086#else 2087 (void) mode; 2088#endif 2089 return GL_FALSE; 2090} 2091 2092 2093 2094#ifdef FX 2095/* 2096 * Read image from VooDoo frame buffer into X/Mesa's back XImage. 2097 */ 2098static void FXgetImage( XMesaBuffer b ) 2099{ 2100 GET_CURRENT_CONTEXT(ctx); 2101 static unsigned short pixbuf[MAX_WIDTH]; 2102 GLuint x, y; 2103 GLuint width, height; 2104 XMesaContext xmesa = XMESA_CONTEXT(ctx); 2105 2106#ifdef XFree86Server 2107 x = b->frontxrb->pixmap->x; 2108 y = b->frontxrb->pixmap->y; 2109 width = b->frontxrb->pixmap->width; 2110 height = b->frontxrb->pixmap->height; 2111 depth = b->frontxrb->pixmap->depth; 2112#else 2113 xmesa_get_window_size(b->display, b, &width, &height); 2114 x = y = 0; 2115#endif 2116 if (b->mesa_buffer.Width != width || b->mesa_buffer.Height != height) { 2117 b->mesa_buffer.Width = MIN2((int)width, b->FXctx->width); 2118 b->mesa_buffer.Height = MIN2((int)height, b->FXctx->height); 2119 if (b->mesa_buffer.Width & 1) 2120 b->mesa_buffer.Width--; /* prevent odd width */ 2121 } 2122 2123 /* [dBorca] we're always in the right GR_COLORFORMAT... aren't we? */ 2124 /* grLfbWriteColorFormat(GR_COLORFORMAT_ARGB); */ 2125 if (b->xm_visual->undithered_pf==PF_5R6G5B) { 2126 /* Special case: 16bpp RGB */ 2127 grLfbReadRegion( GR_BUFFER_FRONTBUFFER, /* src buffer */ 2128 0, b->FXctx->height - b->mesa_buffer.Height, /*pos*/ 2129 b->mesa_buffer.Width, b->mesa_buffer.Height, /* size */ 2130 b->mesa_buffer.Width * sizeof(GLushort), /* stride */ 2131 b->backxrb->ximage->data); /* dest buffer */ 2132 } 2133 else if (b->xm_visual->dithered_pf==PF_Dither 2134 && GET_VISUAL_DEPTH(b->xm_visual)==8) { 2135 /* Special case: 8bpp RGB */ 2136 for (y=0;y<b->mesa_buffer.Height;y++) { 2137 GLubyte *ptr = (GLubyte*) b->backxrb->ximage->data 2138 + b->backxrb->ximage->bytes_per_line * y; 2139 XDITHER_SETUP(y); 2140 2141 /* read row from 3Dfx frame buffer */ 2142 grLfbReadRegion( GR_BUFFER_FRONTBUFFER, 2143 0, b->FXctx->height-(b->mesa_buffer.Height-y), 2144 b->mesa_buffer.Width, 1, 2145 0, 2146 pixbuf ); 2147 2148 /* write to XImage back buffer */ 2149 for (x=0;x<b->mesa_buffer.Width;x++) { 2150 GLubyte r = (pixbuf[x] & 0xf800) >> 8; 2151 GLubyte g = (pixbuf[x] & 0x07e0) >> 3; 2152 GLubyte b = (pixbuf[x] & 0x001f) << 3; 2153 *ptr++ = XDITHER( x, r, g, b); 2154 } 2155 } 2156 } 2157 else { 2158 /* General case: slow! */ 2159 for (y=0;y<b->mesa_buffer.Height;y++) { 2160 /* read row from 3Dfx frame buffer */ 2161 grLfbReadRegion( GR_BUFFER_FRONTBUFFER, 2162 0, b->FXctx->height-(b->mesa_buffer.Height-y), 2163 b->mesa_buffer.Width, 1, 2164 0, 2165 pixbuf ); 2166 2167 /* write to XImage back buffer */ 2168 for (x=0;x<b->mesa_buffer.Width;x++) { 2169 XMesaPutPixel(b->backxrb->ximage,x,y, 2170 xmesa_color_to_pixel(ctx, 2171 (pixbuf[x] & 0xf800) >> 8, 2172 (pixbuf[x] & 0x07e0) >> 3, 2173 (pixbuf[x] & 0x001f) << 3, 2174 0xff, 2175 b->xm_visual->undithered_pf)); 2176 } 2177 } 2178 } 2179 /* grLfbWriteColorFormat(GR_COLORFORMAT_ABGR); */ 2180} 2181#endif 2182 2183 2184/* 2185 * Copy the back buffer to the front buffer. If there's no back buffer 2186 * this is a no-op. 2187 */ 2188void XMesaSwapBuffers( XMesaBuffer b ) 2189{ 2190 GET_CURRENT_CONTEXT(ctx); 2191 2192 if (!b->backxrb) { 2193 /* single buffered */ 2194 return; 2195 } 2196 2197 /* If we're swapping the buffer associated with the current context 2198 * we have to flush any pending rendering commands first. 2199 */ 2200 if (ctx && ctx->DrawBuffer == &(b->mesa_buffer)) 2201 _mesa_notifySwapBuffers(ctx); 2202 2203 if (b->db_mode) { 2204#ifdef FX 2205 if (b->FXctx) { 2206 fxMesaSwapBuffers(); 2207 2208 if (b->FXwindowHack) 2209 FXgetImage(b); 2210 else 2211 return; 2212 } 2213#endif 2214 if (b->backxrb->ximage) { 2215 /* Copy Ximage from host's memory to server's window */ 2216#if defined(USE_XSHM) && !defined(XFree86Server) 2217 if (b->shm) { 2218 /*_glthread_LOCK_MUTEX(_xmesa_lock);*/ 2219 XShmPutImage( b->xm_visual->display, b->frontxrb->drawable, 2220 b->swapgc, 2221 b->backxrb->ximage, 0, 0, 2222 0, 0, b->mesa_buffer.Width, b->mesa_buffer.Height, 2223 False ); 2224 /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/ 2225 } 2226 else 2227#endif 2228 { 2229 /*_glthread_LOCK_MUTEX(_xmesa_lock);*/ 2230 XMesaPutImage( b->xm_visual->display, b->frontxrb->drawable, 2231 b->swapgc, 2232 b->backxrb->ximage, 0, 0, 2233 0, 0, b->mesa_buffer.Width, b->mesa_buffer.Height ); 2234 /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/ 2235 } 2236 } 2237 else { 2238 /* Copy pixmap to window on server */ 2239 /*_glthread_LOCK_MUTEX(_xmesa_lock);*/ 2240 XMesaCopyArea( b->xm_visual->display, 2241 b->backxrb->pixmap, /* source drawable */ 2242 b->frontxrb->drawable, /* dest. drawable */ 2243 b->swapgc, 2244 0, 0, b->mesa_buffer.Width, b->mesa_buffer.Height, 2245 0, 0 /* dest region */ 2246 ); 2247 /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/ 2248 } 2249 } 2250#if !defined(XFree86Server) 2251 XSync( b->xm_visual->display, False ); 2252#endif 2253} 2254 2255 2256 2257/* 2258 * Copy sub-region of back buffer to front buffer 2259 */ 2260void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height ) 2261{ 2262 GET_CURRENT_CONTEXT(ctx); 2263 2264 /* If we're swapping the buffer associated with the current context 2265 * we have to flush any pending rendering commands first. 2266 */ 2267 if (ctx && ctx->DrawBuffer == &(b->mesa_buffer)) 2268 _mesa_notifySwapBuffers(ctx); 2269 2270 if (!b->backxrb) { 2271 /* single buffered */ 2272 return; 2273 } 2274 2275 if (b->db_mode) { 2276 int yTop = b->mesa_buffer.Height - y - height; 2277#ifdef FX 2278 if (b->FXctx) { 2279 fxMesaSwapBuffers(); 2280 if (b->FXwindowHack) 2281 FXgetImage(b); 2282 else 2283 return; 2284 } 2285#endif 2286 if (b->backxrb->ximage) { 2287 /* Copy Ximage from host's memory to server's window */ 2288#if defined(USE_XSHM) && !defined(XFree86Server) 2289 if (b->shm) { 2290 /* XXX assuming width and height aren't too large! */ 2291 XShmPutImage( b->xm_visual->display, b->frontxrb->drawable, 2292 b->swapgc, 2293 b->backxrb->ximage, x, yTop, 2294 x, yTop, width, height, False ); 2295 /* wait for finished event??? */ 2296 } 2297 else 2298#endif 2299 { 2300 /* XXX assuming width and height aren't too large! */ 2301 XMesaPutImage( b->xm_visual->display, b->frontxrb->drawable, 2302 b->swapgc, 2303 b->backxrb->ximage, x, yTop, 2304 x, yTop, width, height ); 2305 } 2306 } 2307 else { 2308 /* Copy pixmap to window on server */ 2309 XMesaCopyArea( b->xm_visual->display, 2310 b->backxrb->pixmap, /* source drawable */ 2311 b->frontxrb->drawable, /* dest. drawable */ 2312 b->swapgc, 2313 x, yTop, width, height, /* source region */ 2314 x, yTop /* dest region */ 2315 ); 2316 } 2317 } 2318} 2319 2320 2321/* 2322 * Return a pointer to the XMesa backbuffer Pixmap or XImage. This function 2323 * is a way to get "under the hood" of X/Mesa so one can manipulate the 2324 * back buffer directly. 2325 * Output: pixmap - pointer to back buffer's Pixmap, or 0 2326 * ximage - pointer to back buffer's XImage, or NULL 2327 * Return: GL_TRUE = context is double buffered 2328 * GL_FALSE = context is single buffered 2329 */ 2330#ifndef XFree86Server 2331GLboolean XMesaGetBackBuffer( XMesaBuffer b, 2332 XMesaPixmap *pixmap, 2333 XMesaImage **ximage ) 2334{ 2335 if (b->db_mode) { 2336 if (pixmap) 2337 *pixmap = b->backxrb->pixmap; 2338 if (ximage) 2339 *ximage = b->backxrb->ximage; 2340 return GL_TRUE; 2341 } 2342 else { 2343 *pixmap = 0; 2344 *ximage = NULL; 2345 return GL_FALSE; 2346 } 2347} 2348#endif /* XFree86Server */ 2349 2350 2351/* 2352 * Return the depth buffer associated with an XMesaBuffer. 2353 * Input: b - the XMesa buffer handle 2354 * Output: width, height - size of buffer in pixels 2355 * bytesPerValue - bytes per depth value (2 or 4) 2356 * buffer - pointer to depth buffer values 2357 * Return: GL_TRUE or GL_FALSE to indicate success or failure. 2358 */ 2359GLboolean XMesaGetDepthBuffer( XMesaBuffer b, GLint *width, GLint *height, 2360 GLint *bytesPerValue, void **buffer ) 2361{ 2362 struct gl_renderbuffer *rb 2363 = b->mesa_buffer.Attachment[BUFFER_DEPTH].Renderbuffer; 2364 if (!rb || !rb->Data) { 2365 *width = 0; 2366 *height = 0; 2367 *bytesPerValue = 0; 2368 *buffer = 0; 2369 return GL_FALSE; 2370 } 2371 else { 2372 *width = b->mesa_buffer.Width; 2373 *height = b->mesa_buffer.Height; 2374 *bytesPerValue = b->mesa_buffer.Visual.depthBits <= 16 2375 ? sizeof(GLushort) : sizeof(GLuint); 2376 *buffer = rb->Data; 2377 return GL_TRUE; 2378 } 2379} 2380 2381 2382void XMesaFlush( XMesaContext c ) 2383{ 2384 if (c && c->xm_visual) { 2385#ifdef XFree86Server 2386 /* NOT_NEEDED */ 2387#else 2388 XSync( c->xm_visual->display, False ); 2389#endif 2390 } 2391} 2392 2393 2394 2395const char *XMesaGetString( XMesaContext c, int name ) 2396{ 2397 (void) c; 2398 if (name==XMESA_VERSION) { 2399 return "5.0"; 2400 } 2401 else if (name==XMESA_EXTENSIONS) { 2402 return ""; 2403 } 2404 else { 2405 return NULL; 2406 } 2407} 2408 2409 2410 2411XMesaBuffer XMesaFindBuffer( XMesaDisplay *dpy, XMesaDrawable d ) 2412{ 2413 XMesaBuffer b; 2414 for (b=XMesaBufferList; b; b=b->Next) { 2415 if (b->frontxrb->drawable == d && b->display == dpy) { 2416 return b; 2417 } 2418 } 2419 return NULL; 2420} 2421 2422 2423/** 2424 * Free/destroy all XMesaBuffers associated with given display. 2425 */ 2426void xmesa_destroy_buffers_on_display(XMesaDisplay *dpy) 2427{ 2428 XMesaBuffer b, next; 2429 for (b = XMesaBufferList; b; b = next) { 2430 next = b->Next; 2431 if (b->display == dpy) { 2432 free_xmesa_buffer(0, b); 2433 } 2434 } 2435} 2436 2437 2438/* 2439 * Look for XMesaBuffers whose X window has been destroyed. 2440 * Deallocate any such XMesaBuffers. 2441 */ 2442void XMesaGarbageCollect( void ) 2443{ 2444 XMesaBuffer b, next; 2445 for (b=XMesaBufferList; b; b=next) { 2446 next = b->Next; 2447 if (b->display && b->frontxrb->drawable && b->type == WINDOW) { 2448#ifdef XFree86Server 2449 /* NOT_NEEDED */ 2450#else 2451 XSync(b->display, False); 2452 if (!window_exists( b->display, b->frontxrb->drawable )) { 2453 /* found a dead window, free the ancillary info */ 2454 XMesaDestroyBuffer( b ); 2455 } 2456#endif 2457 } 2458 } 2459} 2460 2461 2462void XMesaReset( void ) 2463{ 2464 while (XMesaBufferList) 2465 XMesaDestroyBuffer(XMesaBufferList); 2466 2467 XMesaBufferList = NULL; 2468} 2469 2470 2471unsigned long XMesaDitherColor( XMesaContext xmesa, GLint x, GLint y, 2472 GLfloat red, GLfloat green, 2473 GLfloat blue, GLfloat alpha ) 2474{ 2475 GLcontext *ctx = &xmesa->mesa; 2476 GLint r = (GLint) (red * 255.0F); 2477 GLint g = (GLint) (green * 255.0F); 2478 GLint b = (GLint) (blue * 255.0F); 2479 GLint a = (GLint) (alpha * 255.0F); 2480 2481 switch (xmesa->pixelformat) { 2482 case PF_Index: 2483 return 0; 2484 case PF_Truecolor: 2485 { 2486 unsigned long p; 2487 PACK_TRUECOLOR( p, r, g, b ); 2488 return p; 2489 } 2490 case PF_8A8B8G8R: 2491 return PACK_8A8B8G8R( r, g, b, a ); 2492 case PF_8A8R8G8B: 2493 return PACK_8A8R8G8B( r, g, b, a ); 2494 case PF_8R8G8B: 2495 return PACK_8R8G8B( r, g, b ); 2496 case PF_5R6G5B: 2497 return PACK_5R6G5B( r, g, b ); 2498 case PF_Dither: 2499 { 2500 DITHER_SETUP; 2501 return DITHER( x, y, r, g, b ); 2502 } 2503 case PF_1Bit: 2504 /* 382 = (3*255)/2 */ 2505 return ((r+g+b) > 382) ^ xmesa->xm_visual->bitFlip; 2506 case PF_HPCR: 2507 return DITHER_HPCR(x, y, r, g, b); 2508 case PF_Lookup: 2509 { 2510 LOOKUP_SETUP; 2511 return LOOKUP( r, g, b ); 2512 } 2513 case PF_Grayscale: 2514 return GRAY_RGB( r, g, b ); 2515 case PF_Dither_5R6G5B: 2516 /* fall through */ 2517 case PF_Dither_True: 2518 { 2519 unsigned long p; 2520 PACK_TRUEDITHER(p, x, y, r, g, b); 2521 return p; 2522 } 2523 default: 2524 _mesa_problem(NULL, "Bad pixel format in XMesaDitherColor"); 2525 } 2526 return 0; 2527} 2528 2529 2530/* 2531 * This is typically called when the window size changes and we need 2532 * to reallocate the buffer's back/depth/stencil/accum buffers. 2533 */ 2534void 2535XMesaResizeBuffers( XMesaBuffer b ) 2536{ 2537 GET_CURRENT_CONTEXT(ctx); 2538 XMesaContext xmctx = XMESA_CONTEXT(ctx); 2539 xmesa_check_and_update_buffer_size(xmctx, b); 2540} 2541 2542