1e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul/* 2e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Mesa 3-D graphics library 3d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * Version: 6.5.2 4e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * 5d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 6e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * 7e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Permission is hereby granted, free of charge, to any person obtaining a 8e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * copy of this software and associated documentation files (the "Software"), 9e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * to deal in the Software without restriction, including without limitation 10e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * and/or sell copies of the Software, and to permit persons to whom the 12e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Software is furnished to do so, subject to the following conditions: 13e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * 14e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * The above copyright notice and this permission notice shall be included 15e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * in all copies or substantial portions of the Software. 16e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * 17e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul */ 24e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 25e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 26d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul/** 27d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * \file xm_buffer.h 28d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * Framebuffer and renderbuffer-related functions. 29d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul */ 30d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul 31d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul 32e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul#include "glxheader.h" 33e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul#include "xmesaP.h" 34374e7fd6cc95d3d91629a6e1c951d77e8a29c31cBrian Paul#include "main/imports.h" 3545e76d2665b38ba3787548310efc59e969124c01Brian Paul#include "main/formats.h" 36374e7fd6cc95d3d91629a6e1c951d77e8a29c31cBrian Paul#include "main/framebuffer.h" 37374e7fd6cc95d3d91629a6e1c951d77e8a29c31cBrian Paul#include "main/renderbuffer.h" 38d0dc75c000d5af92648c7de901756400672b8447Brian Paul#include "swrast/s_renderbuffer.h" 39e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 40e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 4132c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul#define XMESA_RENDERBUFFER 0x1234 4232c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 4332c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 441ccef926be46dce3b6b5c76e812e2fae4e205ce7Adam Jackson#if defined(USE_XSHM) 45d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paulstatic volatile int mesaXErrorFlag = 0; 46d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul 47d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul/** 48d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * Catches potential Xlib errors. 49d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul */ 50d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paulstatic int 51d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian PaulmesaHandleXError(XMesaDisplay *dpy, XErrorEvent *event) 52d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul{ 53d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul (void) dpy; 54d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul (void) event; 55d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul mesaXErrorFlag = 1; 56d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul return 0; 57d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul} 58d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul 59d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul/** 60d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * Allocate a shared memory XImage back buffer for the given XMesaBuffer. 61d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * Return: GL_TRUE if success, GL_FALSE if error 62d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul */ 63d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paulstatic GLboolean 64d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paulalloc_back_shm_ximage(XMesaBuffer b, GLuint width, GLuint height) 65d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul{ 66d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul /* 67d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * We have to do a _lot_ of error checking here to be sure we can 68d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * really use the XSHM extension. It seems different servers trigger 69d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * errors at different points if the extension won't work. Therefore 70d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * we have to be very careful... 71d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul */ 72d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul GC gc; 73d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul int (*old_handler)(XMesaDisplay *, XErrorEvent *); 74d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul 75d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul if (width == 0 || height == 0) { 76d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul /* this will be true the first time we're called on 'b' */ 77d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul return GL_FALSE; 78d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul } 79d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul 80d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul b->backxrb->ximage = XShmCreateImage(b->xm_visual->display, 81d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul b->xm_visual->visinfo->visual, 82d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul b->xm_visual->visinfo->depth, 83d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul ZPixmap, NULL, &b->shminfo, 84d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul width, height); 85d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul if (b->backxrb->ximage == NULL) { 86d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (XShmCreateImage), disabling.\n"); 87d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul b->shm = 0; 88d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul return GL_FALSE; 89d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul } 90d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul 91d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul b->shminfo.shmid = shmget(IPC_PRIVATE, b->backxrb->ximage->bytes_per_line 92d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * b->backxrb->ximage->height, IPC_CREAT|0777); 93d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul if (b->shminfo.shmid < 0) { 94d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul _mesa_warning(NULL, "shmget failed while allocating back buffer.\n"); 95d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul XDestroyImage(b->backxrb->ximage); 96d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul b->backxrb->ximage = NULL; 97d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmget), disabling.\n"); 98d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul b->shm = 0; 99d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul return GL_FALSE; 100d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul } 101d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul 102d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul b->shminfo.shmaddr = b->backxrb->ximage->data 103d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul = (char*)shmat(b->shminfo.shmid, 0, 0); 104d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul if (b->shminfo.shmaddr == (char *) -1) { 105d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul _mesa_warning(NULL, "shmat() failed while allocating back buffer.\n"); 106d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul XDestroyImage(b->backxrb->ximage); 107d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul shmctl(b->shminfo.shmid, IPC_RMID, 0); 108d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul b->backxrb->ximage = NULL; 109d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmat), disabling.\n"); 110d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul b->shm = 0; 111d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul return GL_FALSE; 112d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul } 113d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul 114d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul b->shminfo.readOnly = False; 115d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul mesaXErrorFlag = 0; 116d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul old_handler = XSetErrorHandler(mesaHandleXError); 117d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul /* This may trigger the X protocol error we're ready to catch: */ 118d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul XShmAttach(b->xm_visual->display, &b->shminfo); 119d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul XSync(b->xm_visual->display, False); 120d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul 121d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul if (mesaXErrorFlag) { 122d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul /* we are on a remote display, this error is normal, don't print it */ 123d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul XFlush(b->xm_visual->display); 124d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul mesaXErrorFlag = 0; 125d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul XDestroyImage(b->backxrb->ximage); 126d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul shmdt(b->shminfo.shmaddr); 127d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul shmctl(b->shminfo.shmid, IPC_RMID, 0); 128d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul b->backxrb->ximage = NULL; 129d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul b->shm = 0; 130d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul (void) XSetErrorHandler(old_handler); 131d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul return GL_FALSE; 132d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul } 133d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul 134d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul shmctl(b->shminfo.shmid, IPC_RMID, 0); /* nobody else needs it */ 135d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul 136d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul /* Finally, try an XShmPutImage to be really sure the extension works */ 137d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul gc = XCreateGC(b->xm_visual->display, b->frontxrb->drawable, 0, NULL); 138d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul XShmPutImage(b->xm_visual->display, b->frontxrb->drawable, gc, 139d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul b->backxrb->ximage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False); 140d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul XSync(b->xm_visual->display, False); 141d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul XFreeGC(b->xm_visual->display, gc); 142d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul (void) XSetErrorHandler(old_handler); 143d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul if (mesaXErrorFlag) { 144d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul XFlush(b->xm_visual->display); 145d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul mesaXErrorFlag = 0; 146d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul XDestroyImage(b->backxrb->ximage); 147d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul shmdt(b->shminfo.shmaddr); 148d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul shmctl(b->shminfo.shmid, IPC_RMID, 0); 149d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul b->backxrb->ximage = NULL; 150d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul b->shm = 0; 151d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul return GL_FALSE; 152d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul } 153d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul 154d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul return GL_TRUE; 1557439a36785b6a2783e80a40a96c09db8f56dc2bcGeorge Sapountzis} 156d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul#else 1577439a36785b6a2783e80a40a96c09db8f56dc2bcGeorge Sapountzisstatic GLboolean 1587439a36785b6a2783e80a40a96c09db8f56dc2bcGeorge Sapountzisalloc_back_shm_ximage(XMesaBuffer b, GLuint width, GLuint height) 1597439a36785b6a2783e80a40a96c09db8f56dc2bcGeorge Sapountzis{ 160d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul /* Can't compile XSHM support */ 161d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul return GL_FALSE; 162d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul} 163d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul#endif 164d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul 165d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul 166d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul 167d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul/** 168d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * Setup an off-screen pixmap or Ximage to use as the back buffer. 169d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * Input: b - the X/Mesa buffer 170d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul */ 171d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paulstatic void 172d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paulalloc_back_buffer(XMesaBuffer b, GLuint width, GLuint height) 173d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul{ 174d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul if (b->db_mode == BACK_XIMAGE) { 175d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul /* Deallocate the old backxrb->ximage, if any */ 176d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul if (b->backxrb->ximage) { 1771ccef926be46dce3b6b5c76e812e2fae4e205ce7Adam Jackson#if defined(USE_XSHM) 178d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul if (b->shm) { 179d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul XShmDetach(b->xm_visual->display, &b->shminfo); 180d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul XDestroyImage(b->backxrb->ximage); 181d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul shmdt(b->shminfo.shmaddr); 182d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul } 183d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul else 184d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul#endif 185d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul XMesaDestroyImage(b->backxrb->ximage); 186d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul b->backxrb->ximage = NULL; 187d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul } 188d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul 189e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian if (width == 0 || height == 0) 190e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian return; 191e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian 192d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul /* Allocate new back buffer */ 193d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul if (b->shm == 0 || !alloc_back_shm_ximage(b, width, height)) { 194d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul /* Allocate a regular XImage for the back buffer. */ 195d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul b->backxrb->ximage = XCreateImage(b->xm_visual->display, 196d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul b->xm_visual->visinfo->visual, 197d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul GET_VISUAL_DEPTH(b->xm_visual), 198d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul ZPixmap, 0, /* format, offset */ 199d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul NULL, 200d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul width, height, 201d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul 8, 0); /* pad, bytes_per_line */ 202d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul if (!b->backxrb->ximage) { 203d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul _mesa_warning(NULL, "alloc_back_buffer: XCreateImage failed.\n"); 204d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul return; 205d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul } 206d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul b->backxrb->ximage->data = (char *) MALLOC(b->backxrb->ximage->height 207d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * b->backxrb->ximage->bytes_per_line); 208d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul if (!b->backxrb->ximage->data) { 209d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul _mesa_warning(NULL, "alloc_back_buffer: MALLOC failed.\n"); 210d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul XMesaDestroyImage(b->backxrb->ximage); 211d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul b->backxrb->ximage = NULL; 212d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul } 213d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul } 214d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul b->backxrb->pixmap = None; 215d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul } 216d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul else if (b->db_mode == BACK_PIXMAP) { 217d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul /* Free the old back pixmap */ 218d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul if (b->backxrb->pixmap) { 219e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian XMesaFreePixmap(b->xm_visual->display, b->backxrb->pixmap); 220e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian b->backxrb->pixmap = 0; 221d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul } 222e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian 223e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian if (width > 0 && height > 0) { 224e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian /* Allocate new back pixmap */ 225e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian b->backxrb->pixmap = XMesaCreatePixmap(b->xm_visual->display, 226e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian b->frontxrb->drawable, 227e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian width, height, 228e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian GET_VISUAL_DEPTH(b->xm_visual)); 229e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian } 230e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian 231d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul b->backxrb->ximage = NULL; 23222bac2a1a0d315172f815cb8a516bfe198b0a6f3Brian Paul b->backxrb->drawable = b->backxrb->pixmap; 233d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul } 234d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul} 235d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul 236d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul 237e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulstatic void 2389d4ab9a663d4088ec553edaae0eeafb746d2490dBrian Paulxmesa_delete_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb) 239e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul{ 240d2e289c70f2b9fb882f5b3992b610a9ea5c8357cBrian Paul /* XXX Note: the ximage or Pixmap attached to this renderbuffer 241d2e289c70f2b9fb882f5b3992b610a9ea5c8357cBrian Paul * should probably get freed here, but that's currently done in 242d2e289c70f2b9fb882f5b3992b610a9ea5c8357cBrian Paul * XMesaDestroyBuffer(). 243d2e289c70f2b9fb882f5b3992b610a9ea5c8357cBrian Paul */ 24432f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg free(rb); 245e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul} 246e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 247e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 248e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul/** 249692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul * Reallocate renderbuffer storage for front color buffer. 250e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian * Called via gl_renderbuffer::AllocStorage() 251e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul */ 252e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulstatic GLboolean 253f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergxmesa_alloc_front_storage(struct gl_context *ctx, struct gl_renderbuffer *rb, 254692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul GLenum internalFormat, GLuint width, GLuint height) 255e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul{ 256444cd293fd69d1848b2c55f75674d563e0582fbaBrian Paul struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb); 257e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 258692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul /* just clear these to be sure we don't accidentally use them */ 259692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul xrb->origin2 = NULL; 260e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian xrb->origin3 = NULL; 261692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul xrb->origin4 = NULL; 262692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul 263692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul /* for the FLIP macro: */ 264692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul xrb->bottom = height - 1; 265692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul 266692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul rb->Width = width; 267692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul rb->Height = height; 268692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul rb->InternalFormat = internalFormat; 269692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul 270692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul return GL_TRUE; 271692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul} 272692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul 273692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul 274692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul/** 275692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul * Reallocate renderbuffer storage for back color buffer. 276e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian * Called via gl_renderbuffer::AllocStorage() 277692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul */ 278692147ebf7f09d56a7de1659de2449478da4d1baBrian Paulstatic GLboolean 279f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergxmesa_alloc_back_storage(struct gl_context *ctx, struct gl_renderbuffer *rb, 280692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul GLenum internalFormat, GLuint width, GLuint height) 281692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul{ 282444cd293fd69d1848b2c55f75674d563e0582fbaBrian Paul struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb); 283692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul 284d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul /* reallocate the back buffer XImage or Pixmap */ 285d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul assert(xrb->Parent); 286d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul alloc_back_buffer(xrb->Parent, width, height); 287d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul 288692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul /* same as front buffer */ 289d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul /* XXX why is this here? */ 290692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul (void) xmesa_alloc_front_storage(ctx, rb, internalFormat, width, height); 291692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul 292692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul /* plus... */ 293e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (xrb->ximage) { 294e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* Needed by PIXELADDR2 macro */ 295e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul xrb->width2 = xrb->ximage->bytes_per_line / 2; 296e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul xrb->origin2 = (GLushort *) xrb->ximage->data + xrb->width2 * (height - 1); 297e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 298e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* Needed by PIXELADDR3 macro */ 299e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul xrb->width3 = xrb->ximage->bytes_per_line; 300e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul xrb->origin3 = (GLubyte *) xrb->ximage->data + xrb->width3 * (height - 1); 301e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 302e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* Needed by PIXELADDR4 macro */ 303e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul xrb->width4 = xrb->ximage->width; 304e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul xrb->origin4 = (GLuint *) xrb->ximage->data + xrb->width4 * (height - 1); 305e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 306e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else { 307e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian /* out of memory or buffer size is 0 x 0 */ 308bc63b226bcc94f109906bccce26d47509f28d177Brian Paul xrb->width2 = xrb->width3 = xrb->width4 = 0; 309e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian xrb->origin2 = NULL; 310e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian xrb->origin3 = NULL; 311e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian xrb->origin4 = NULL; 312e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 313e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 314e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul return GL_TRUE; 315e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul} 316e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 317e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 31832c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul/** 31932c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul * Used for allocating front/back renderbuffers for an X window. 32032c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul */ 321e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulstruct xmesa_renderbuffer * 32232c3957991bd0e1df744d866943a8c47b2757c9eBrian Paulxmesa_new_renderbuffer(struct gl_context *ctx, GLuint name, 32332c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul const struct xmesa_visual *xmvis, 324692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul GLboolean backBuffer) 325e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul{ 326e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul struct xmesa_renderbuffer *xrb = CALLOC_STRUCT(xmesa_renderbuffer); 327e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (xrb) { 328e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint name = 0; 329d16e71eeb47d1e67930f6e86a80dc926468224d9Brian Paul _mesa_init_renderbuffer(&xrb->Base.Base, name); 330e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 331d16e71eeb47d1e67930f6e86a80dc926468224d9Brian Paul xrb->Base.Base.Delete = xmesa_delete_renderbuffer; 332692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul if (backBuffer) 333d16e71eeb47d1e67930f6e86a80dc926468224d9Brian Paul xrb->Base.Base.AllocStorage = xmesa_alloc_back_storage; 334692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul else 335d16e71eeb47d1e67930f6e86a80dc926468224d9Brian Paul xrb->Base.Base.AllocStorage = xmesa_alloc_front_storage; 336e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 337d16e71eeb47d1e67930f6e86a80dc926468224d9Brian Paul xrb->Base.Base.InternalFormat = GL_RGBA; 338d16e71eeb47d1e67930f6e86a80dc926468224d9Brian Paul xrb->Base.Base._BaseFormat = GL_RGBA; 339d16e71eeb47d1e67930f6e86a80dc926468224d9Brian Paul xrb->Base.Base.ClassID = XMESA_RENDERBUFFER; 34032c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 34132c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul switch (xmvis->undithered_pf) { 34232c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul case PF_8R8G8B: 34332c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul /* This will really only happen for pixmaps. We'll access the 34432c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul * pixmap via a temporary XImage which will be 32bpp. 34532c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul */ 346d16e71eeb47d1e67930f6e86a80dc926468224d9Brian Paul xrb->Base.Base.Format = MESA_FORMAT_XRGB8888; 34732c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul break; 34832c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul case PF_8A8R8G8B: 349d16e71eeb47d1e67930f6e86a80dc926468224d9Brian Paul xrb->Base.Base.Format = MESA_FORMAT_ARGB8888; 35032c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul break; 35132c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul case PF_8A8B8G8R: 352d16e71eeb47d1e67930f6e86a80dc926468224d9Brian Paul xrb->Base.Base.Format = MESA_FORMAT_RGBA8888_REV; 35332c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul break; 35432c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul case PF_5R6G5B: 355d16e71eeb47d1e67930f6e86a80dc926468224d9Brian Paul xrb->Base.Base.Format = MESA_FORMAT_RGB565; 35632c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul break; 35732c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul default: 35832c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul _mesa_warning(ctx, "Bad pixel format in xmesa_new_renderbuffer"); 359d16e71eeb47d1e67930f6e86a80dc926468224d9Brian Paul xrb->Base.Base.Format = MESA_FORMAT_ARGB8888; 36032c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul break; 36132c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul } 36232c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 363676d0accf5cc43e86057b14cfb8bba9316932582Brian Paul /* only need to set Red/Green/EtcBits fields for user-created RBs */ 364e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 365e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul return xrb; 366e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul} 367e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 368e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 369928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian/** 370928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian * Called via gl_framebuffer::Delete() method when this buffer 37159e56ee3e5c8f9aa9ec74e1817065a7ae14012eaBrian * is _really_ being deleted. 372928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian */ 373928a70e4354d4884e2918ec67ddc6d8baf942c8aBrianvoid 374928a70e4354d4884e2918ec67ddc6d8baf942c8aBrianxmesa_delete_framebuffer(struct gl_framebuffer *fb) 375928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian{ 376928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian XMesaBuffer b = XMESA_BUFFER(fb); 377e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 378928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian if (b->num_alloced > 0) { 379928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian /* If no other buffer uses this X colormap then free the colors. */ 380928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian if (!xmesa_find_buffer(b->display, b->cmap, b)) { 381928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian XFreeColors(b->display, b->cmap, 382928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian b->alloced_colors, b->num_alloced, 0); 383928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian } 384928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian } 385928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian 386928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian if (b->gc) 387e812a2a484660c87383e7e7d8897a9bcf85cf9ccBrian XMesaFreeGC(b->display, b->gc); 388928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian if (b->cleargc) 389e812a2a484660c87383e7e7d8897a9bcf85cf9ccBrian XMesaFreeGC(b->display, b->cleargc); 390928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian if (b->swapgc) 391e812a2a484660c87383e7e7d8897a9bcf85cf9ccBrian XMesaFreeGC(b->display, b->swapgc); 392928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian 393e812a2a484660c87383e7e7d8897a9bcf85cf9ccBrian if (fb->Visual.doubleBufferMode) { 394928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian /* free back ximage/pixmap/shmregion */ 395928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian if (b->backxrb->ximage) { 3961ccef926be46dce3b6b5c76e812e2fae4e205ce7Adam Jackson#if defined(USE_XSHM) 397928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian if (b->shm) { 398e812a2a484660c87383e7e7d8897a9bcf85cf9ccBrian XShmDetach( b->display, &b->shminfo ); 399928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian XDestroyImage( b->backxrb->ximage ); 400928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian shmdt( b->shminfo.shmaddr ); 401928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian } 402928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian else 403928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian#endif 404928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian XMesaDestroyImage( b->backxrb->ximage ); 405928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian b->backxrb->ximage = NULL; 406928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian } 407928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian if (b->backxrb->pixmap) { 408e812a2a484660c87383e7e7d8897a9bcf85cf9ccBrian XMesaFreePixmap( b->display, b->backxrb->pixmap ); 409928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian } 410928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian } 411928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian 412928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian _mesa_free_framebuffer_data(fb); 41332f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg free(fb); 414928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian} 41532c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 41632c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 41732c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul/** 41832c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul * Called via ctx->Driver.MapRenderbuffer() 41932c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul */ 42032c3957991bd0e1df744d866943a8c47b2757c9eBrian Paulvoid 42132c3957991bd0e1df744d866943a8c47b2757c9eBrian Paulxmesa_MapRenderbuffer(struct gl_context *ctx, 42232c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul struct gl_renderbuffer *rb, 42332c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul GLuint x, GLuint y, GLuint w, GLuint h, 42432c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul GLbitfield mode, 42532c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul GLubyte **mapOut, GLint *rowStrideOut) 42632c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul{ 42732c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb); 42832c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 429d16e71eeb47d1e67930f6e86a80dc926468224d9Brian Paul if (xrb->Base.Base.ClassID == XMESA_RENDERBUFFER) { 43032c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul XImage *ximage = xrb->ximage; 43132c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 43232c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul assert(!xrb->map_mode); /* only a single mapping allowed */ 43332c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 43432c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul xrb->map_mode = mode; 43532c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul xrb->map_x = x; 43632c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul xrb->map_y = y; 43732c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul xrb->map_w = w; 43832c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul xrb->map_h = h; 43932c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 44032c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul if (ximage) { 44132c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul int y2 = rb->Height - y - 1; 44232c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 44332c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul *mapOut = (GLubyte *) ximage->data 44432c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul + y2 * ximage->bytes_per_line 44532c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul + x * ximage->bits_per_pixel / 8; 44632c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul } 44732c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul else { 44832c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul /* this must be a pixmap/window renderbuffer */ 449a73e9207da188a65af50da279f1436566c4a8418Brian Paul int (*old_handler)(XMesaDisplay *, XErrorEvent *); 45032c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul int y2 = rb->Height - y - h; 45132c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 45232c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul assert(xrb->pixmap); 45332c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 454a73e9207da188a65af50da279f1436566c4a8418Brian Paul /* Install error handler for XGetImage() in case the the window 455a73e9207da188a65af50da279f1436566c4a8418Brian Paul * isn't mapped. If we fail we'll create a temporary XImage. 456a73e9207da188a65af50da279f1436566c4a8418Brian Paul */ 457a73e9207da188a65af50da279f1436566c4a8418Brian Paul mesaXErrorFlag = 0; 458a73e9207da188a65af50da279f1436566c4a8418Brian Paul old_handler = XSetErrorHandler(mesaHandleXError); 459a73e9207da188a65af50da279f1436566c4a8418Brian Paul 46032c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul /* read pixel data out of the pixmap/window into an XImage */ 46132c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul ximage = XGetImage(xrb->Parent->display, 46232c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul xrb->pixmap, x, y2, w, h, 46332c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul AllPlanes, ZPixmap); 464a73e9207da188a65af50da279f1436566c4a8418Brian Paul 465a73e9207da188a65af50da279f1436566c4a8418Brian Paul XSetErrorHandler(old_handler); 466a73e9207da188a65af50da279f1436566c4a8418Brian Paul 467a73e9207da188a65af50da279f1436566c4a8418Brian Paul if (mesaXErrorFlag) { 468a73e9207da188a65af50da279f1436566c4a8418Brian Paul /* create new, temporary XImage */ 469a73e9207da188a65af50da279f1436566c4a8418Brian Paul int bytes_per_line = 470a73e9207da188a65af50da279f1436566c4a8418Brian Paul _mesa_format_row_stride(xrb->Base.Base.Format, 471a73e9207da188a65af50da279f1436566c4a8418Brian Paul xrb->Base.Base.Width); 472a73e9207da188a65af50da279f1436566c4a8418Brian Paul char *image = (char *) malloc(bytes_per_line * 473a73e9207da188a65af50da279f1436566c4a8418Brian Paul xrb->Base.Base.Height); 474a73e9207da188a65af50da279f1436566c4a8418Brian Paul ximage = XCreateImage(xrb->Parent->display, 475a73e9207da188a65af50da279f1436566c4a8418Brian Paul xrb->Parent->xm_visual->visinfo->visual, 476a73e9207da188a65af50da279f1436566c4a8418Brian Paul xrb->Parent->xm_visual->visinfo->depth, 477a73e9207da188a65af50da279f1436566c4a8418Brian Paul ZPixmap, /* format */ 478a73e9207da188a65af50da279f1436566c4a8418Brian Paul 0, /* offset */ 479a73e9207da188a65af50da279f1436566c4a8418Brian Paul image, /* data */ 480a73e9207da188a65af50da279f1436566c4a8418Brian Paul xrb->Base.Base.Width, 481a73e9207da188a65af50da279f1436566c4a8418Brian Paul xrb->Base.Base.Height, 482a73e9207da188a65af50da279f1436566c4a8418Brian Paul 8, /* pad */ 483a73e9207da188a65af50da279f1436566c4a8418Brian Paul bytes_per_line); 484a73e9207da188a65af50da279f1436566c4a8418Brian Paul } 485a73e9207da188a65af50da279f1436566c4a8418Brian Paul 48632c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul if (!ximage) { 48732c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul *mapOut = NULL; 48832c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul *rowStrideOut = 0; 48932c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul return; 49032c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul } 49132c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 49232c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul xrb->map_ximage = ximage; 49332c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 49432c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul /* the first row of the OpenGL image is last row of the XImage */ 49532c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul *mapOut = (GLubyte *) ximage->data 49632c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul + (h - 1) * ximage->bytes_per_line; 49732c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul } 49832c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 49932c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul /* We return a negative stride here since XImage data is upside down 50032c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul * with respect to OpenGL images. 50132c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul */ 50232c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul *rowStrideOut = -ximage->bytes_per_line; 50332c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul return; 50432c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul } 50532c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 50632c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul /* otherwise, this is an ordinary malloc-based renderbuffer */ 507d0dc75c000d5af92648c7de901756400672b8447Brian Paul _swrast_map_soft_renderbuffer(ctx, rb, x, y, w, h, mode, 508d0dc75c000d5af92648c7de901756400672b8447Brian Paul mapOut, rowStrideOut); 50932c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul} 51032c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 51132c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 51232c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul/** 51332c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul * Called via ctx->Driver.UnmapRenderbuffer() 51432c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul */ 51532c3957991bd0e1df744d866943a8c47b2757c9eBrian Paulvoid 51632c3957991bd0e1df744d866943a8c47b2757c9eBrian Paulxmesa_UnmapRenderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb) 51732c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul{ 51832c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb); 51932c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 520d16e71eeb47d1e67930f6e86a80dc926468224d9Brian Paul if (xrb->Base.Base.ClassID == XMESA_RENDERBUFFER) { 52132c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul XImage *ximage = xrb->ximage; 52232c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 52332c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul if (!ximage) { 52432c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul /* this must be a pixmap/window renderbuffer */ 52532c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul assert(xrb->pixmap); 52632c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul assert(xrb->map_ximage); 52732c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul if (xrb->map_ximage) { 52832c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul if (xrb->map_mode & GL_MAP_WRITE_BIT) { 52932c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul /* put modified ximage data back into the pixmap/window */ 53032c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul int y2 = rb->Height - xrb->map_y - xrb->map_h; 53132c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul GC gc = XCreateGC(xrb->Parent->display, xrb->pixmap, 0, NULL); 53232c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 53332c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul XPutImage(xrb->Parent->display, 53432c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul xrb->pixmap, /* dest */ 53532c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul gc, 53632c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul xrb->map_ximage, /* source */ 53732c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 0, 0, /* src x, y */ 53832c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul xrb->map_x, y2, /* dest x, y */ 53932c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul xrb->map_w, xrb->map_h); /* size */ 54032c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 54132c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul XFreeGC(xrb->Parent->display, gc); 54232c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul } 54332c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul XMesaDestroyImage(xrb->map_ximage); 54432c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul xrb->map_ximage = NULL; 54532c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul } 54632c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul } 54732c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 54832c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul xrb->map_mode = 0x0; 54932c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 55032c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul return; 55132c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul } 55232c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 55332c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul /* otherwise, this is an ordinary malloc-based renderbuffer */ 554d0dc75c000d5af92648c7de901756400672b8447Brian Paul _swrast_unmap_soft_renderbuffer(ctx, rb); 55532c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul} 55632c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 55732c3957991bd0e1df744d866943a8c47b2757c9eBrian Paul 558