blob: e5fef1d7a81abcb2684f137b6b0ffb97a8b62ad0 [file] [log] [blame]
Brianef25c492007-10-31 14:19:09 -06001/*
2 * Mesa 3-D graphics library
3 * Version: 7.1
4 *
5 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25/**
26 * \file xm_api.c
27 *
28 * All the XMesa* API functions.
29 *
30 *
31 * NOTES:
32 *
33 * The window coordinate system origin (0,0) is in the lower-left corner
34 * of the window. X11's window coordinate origin is in the upper-left
35 * corner of the window. Therefore, most drawing functions in this
36 * file have to flip Y coordinates.
37 *
38 * Define USE_XSHM in the Makefile with -DUSE_XSHM if you want to compile
39 * in support for the MIT Shared Memory extension. If enabled, when you
40 * use an Ximage for the back buffer in double buffered mode, the "swap"
41 * operation will be faster. You must also link with -lXext.
42 *
43 * Byte swapping: If the Mesa host and the X display use a different
44 * byte order then there's some trickiness to be aware of when using
45 * XImages. The byte ordering used for the XImage is that of the X
46 * display, not the Mesa host.
47 * The color-to-pixel encoding for True/DirectColor must be done
48 * according to the display's visual red_mask, green_mask, and blue_mask.
49 * If XPutPixel is used to put a pixel into an XImage then XPutPixel will
50 * do byte swapping if needed. If one wants to directly "poke" the pixel
Brian749d7232007-12-07 07:57:54 -070051 * into the XImage's buffer then the pixel must be byte swapped first.
Brianef25c492007-10-31 14:19:09 -060052 *
53 */
54
55#ifdef __CYGWIN__
56#undef WIN32
57#undef __WIN32__
58#endif
59
60#include "glxheader.h"
61#include "GL/xmesa.h"
62#include "xmesaP.h"
Brian6f467e52007-12-11 19:16:26 -070063#include "main/context.h"
64#include "main/framebuffer.h"
65#include "glapi/glthread.h"
Brianef25c492007-10-31 14:19:09 -060066
67#include "state_tracker/st_public.h"
68#include "state_tracker/st_context.h"
Brianef25c492007-10-31 14:19:09 -060069#include "pipe/p_defines.h"
Brian749d7232007-12-07 07:57:54 -070070#include "pipe/p_context.h"
Brianef25c492007-10-31 14:19:09 -060071
Zack Rusinc474f1f2007-12-11 07:19:11 -050072#include "xm_winsys_aub.h"
73
Brianef25c492007-10-31 14:19:09 -060074/**
75 * Global X driver lock
76 */
77_glthread_Mutex _xmesa_lock;
78
79
Zack Rusinc474f1f2007-12-11 07:19:11 -050080int xmesa_mode;
81
Brianef25c492007-10-31 14:19:09 -060082
Brianef25c492007-10-31 14:19:09 -060083/**********************************************************************/
84/***** X Utility Functions *****/
85/**********************************************************************/
86
87
88/**
89 * Return the host's byte order as LSBFirst or MSBFirst ala X.
90 */
91#ifndef XFree86Server
92static int host_byte_order( void )
93{
94 int i = 1;
95 char *cptr = (char *) &i;
96 return (*cptr==1) ? LSBFirst : MSBFirst;
97}
98#endif
99
100
101/**
102 * Check if the X Shared Memory extension is available.
103 * Return: 0 = not available
104 * 1 = shared XImage support available
105 * 2 = shared Pixmap support available also
106 */
107static int check_for_xshm( XMesaDisplay *display )
108{
109#if defined(USE_XSHM) && !defined(XFree86Server)
110 int major, minor, ignore;
111 Bool pixmaps;
112
113 if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) {
114 if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) {
115 return (pixmaps==True) ? 2 : 1;
116 }
117 else {
118 return 0;
119 }
120 }
121 else {
122 return 0;
123 }
124#else
125 /* No XSHM support */
126 return 0;
127#endif
128}
129
130
131/**
Brianef25c492007-10-31 14:19:09 -0600132 * Return the true number of bits per pixel for XImages.
133 * For example, if we request a 24-bit deep visual we may actually need/get
134 * 32bpp XImages. This function returns the appropriate bpp.
135 * Input: dpy - the X display
136 * visinfo - desribes the visual to be used for XImages
137 * Return: true number of bits per pixel for XImages
138 */
139static int
140bits_per_pixel( XMesaVisual xmv )
141{
142#ifdef XFree86Server
143 const int depth = xmv->nplanes;
144 int i;
145 assert(depth > 0);
146 for (i = 0; i < screenInfo.numPixmapFormats; i++) {
147 if (screenInfo.formats[i].depth == depth)
148 return screenInfo.formats[i].bitsPerPixel;
149 }
150 return depth; /* should never get here, but this should be safe */
151#else
152 XMesaDisplay *dpy = xmv->display;
153 XMesaVisualInfo visinfo = xmv->visinfo;
154 XMesaImage *img;
155 int bitsPerPixel;
156 /* Create a temporary XImage */
157 img = XCreateImage( dpy, visinfo->visual, visinfo->depth,
158 ZPixmap, 0, /*format, offset*/
159 (char*) MALLOC(8), /*data*/
160 1, 1, /*width, height*/
161 32, /*bitmap_pad*/
162 0 /*bytes_per_line*/
163 );
164 assert(img);
165 /* grab the bits/pixel value */
166 bitsPerPixel = img->bits_per_pixel;
167 /* free the XImage */
168 _mesa_free( img->data );
169 img->data = NULL;
170 XMesaDestroyImage( img );
171 return bitsPerPixel;
172#endif
173}
174
175
176
177/*
178 * Determine if a given X window ID is valid (window exists).
179 * Do this by calling XGetWindowAttributes() for the window and
180 * checking if we catch an X error.
181 * Input: dpy - the display
182 * win - the window to check for existance
183 * Return: GL_TRUE - window exists
184 * GL_FALSE - window doesn't exist
185 */
186#ifndef XFree86Server
187static GLboolean WindowExistsFlag;
188
189static int window_exists_err_handler( XMesaDisplay* dpy, XErrorEvent* xerr )
190{
191 (void) dpy;
192 if (xerr->error_code == BadWindow) {
193 WindowExistsFlag = GL_FALSE;
194 }
195 return 0;
196}
197
198static GLboolean window_exists( XMesaDisplay *dpy, Window win )
199{
200 XWindowAttributes wa;
201 int (*old_handler)( XMesaDisplay*, XErrorEvent* );
202 WindowExistsFlag = GL_TRUE;
203 old_handler = XSetErrorHandler(window_exists_err_handler);
204 XGetWindowAttributes( dpy, win, &wa ); /* dummy request */
205 XSetErrorHandler(old_handler);
206 return WindowExistsFlag;
207}
208
209static Status
Brianc6643022007-12-19 13:45:00 -0700210get_drawable_size( XMesaDisplay *dpy, Drawable d, uint *width, uint *height )
Brianef25c492007-10-31 14:19:09 -0600211{
212 Window root;
213 Status stat;
214 int xpos, ypos;
215 unsigned int w, h, bw, depth;
216 stat = XGetGeometry(dpy, d, &root, &xpos, &ypos, &w, &h, &bw, &depth);
217 *width = w;
218 *height = h;
219 return stat;
220}
221#endif
222
223
224/**
225 * Return the size of the window (or pixmap) that corresponds to the
226 * given XMesaBuffer.
227 * \param width returns width in pixels
228 * \param height returns height in pixels
229 */
Brian749d7232007-12-07 07:57:54 -0700230static void
Brianef25c492007-10-31 14:19:09 -0600231xmesa_get_window_size(XMesaDisplay *dpy, XMesaBuffer b,
232 GLuint *width, GLuint *height)
233{
234#ifdef XFree86Server
Brian749d7232007-12-07 07:57:54 -0700235 *width = MIN2(b->drawable->width, MAX_WIDTH);
236 *height = MIN2(b->drawable->height, MAX_HEIGHT);
Brianef25c492007-10-31 14:19:09 -0600237#else
238 Status stat;
239
240 _glthread_LOCK_MUTEX(_xmesa_lock);
241 XSync(b->xm_visual->display, 0); /* added for Chromium */
Brian749d7232007-12-07 07:57:54 -0700242 stat = get_drawable_size(dpy, b->drawable, width, height);
Brianef25c492007-10-31 14:19:09 -0600243 _glthread_UNLOCK_MUTEX(_xmesa_lock);
244
245 if (!stat) {
246 /* probably querying a window that's recently been destroyed */
247 _mesa_warning(NULL, "XGetGeometry failed!\n");
248 *width = *height = 1;
249 }
250#endif
251}
252
253
Brian20eae592007-12-12 14:55:57 -0700254/**
255 * Choose the pixel format for the given visual.
256 * This will tell the gallium driver how to pack pixel data into
257 * drawing surfaces.
258 */
259static GLuint
260choose_pixel_format(XMesaVisual v)
261{
262 if ( GET_REDMASK(v) == 0x0000ff
263 && GET_GREENMASK(v) == 0x00ff00
264 && GET_BLUEMASK(v) == 0xff0000
265 && v->BitsPerPixel == 32) {
266 if (CHECK_BYTE_ORDER(v)) {
267 /* no byteswapping needed */
268 return 0 /* PIXEL_FORMAT_U_A8_B8_G8_R8 */;
269 }
270 else {
271 return PIPE_FORMAT_R8G8B8A8_UNORM;
272 }
273 }
274 else if ( GET_REDMASK(v) == 0xff0000
275 && GET_GREENMASK(v) == 0x00ff00
276 && GET_BLUEMASK(v) == 0x0000ff
277 && v->BitsPerPixel == 32) {
278 if (CHECK_BYTE_ORDER(v)) {
279 /* no byteswapping needed */
280 return PIPE_FORMAT_A8R8G8B8_UNORM;
281 }
282 else {
283 return PIPE_FORMAT_B8G8R8A8_UNORM;
284 }
285 }
286 else if ( GET_REDMASK(v) == 0xf800
287 && GET_GREENMASK(v) == 0x07e0
288 && GET_BLUEMASK(v) == 0x001f
289 && CHECK_BYTE_ORDER(v)
290 && v->BitsPerPixel == 16) {
291 /* 5-6-5 RGB */
292 return PIPE_FORMAT_R5G6B5_UNORM;
293 }
294
295 assert(0);
296 return 0;
297}
298
299
Brianef25c492007-10-31 14:19:09 -0600300
301/**********************************************************************/
302/***** Linked list of XMesaBuffers *****/
303/**********************************************************************/
304
305XMesaBuffer XMesaBufferList = NULL;
306
307
308/**
309 * Allocate a new XMesaBuffer object which corresponds to the given drawable.
310 * Note that XMesaBuffer is derived from GLframebuffer.
311 * The new XMesaBuffer will not have any size (Width=Height=0).
312 *
313 * \param d the corresponding X drawable (window or pixmap)
314 * \param type either WINDOW, PIXMAP or PBUFFER, describing d
315 * \param vis the buffer's visual
316 * \param cmap the window's colormap, if known.
317 * \return new XMesaBuffer or NULL if any problem
318 */
319static XMesaBuffer
320create_xmesa_buffer(XMesaDrawable d, BufferType type,
321 XMesaVisual vis, XMesaColormap cmap)
322{
323 XMesaBuffer b;
Briane39f1b42007-11-05 15:59:55 -0700324 GLframebuffer *fb;
Brian20eae592007-12-12 14:55:57 -0700325 enum pipe_format colorFormat, depthFormat, stencilFormat;
Brianc6643022007-12-19 13:45:00 -0700326 uint width, height;
Brianef25c492007-10-31 14:19:09 -0600327
328 ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER);
329
330 b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer);
331 if (!b)
332 return NULL;
333
Brian749d7232007-12-07 07:57:54 -0700334 b->drawable = d;
335
Brianef25c492007-10-31 14:19:09 -0600336 b->xm_visual = vis;
337 b->type = type;
338 b->cmap = cmap;
339
Brian20eae592007-12-12 14:55:57 -0700340 /* determine PIPE_FORMATs for buffers */
341 colorFormat = choose_pixel_format(vis);
342
343 if (vis->mesa_visual.depthBits == 0)
344 depthFormat = PIPE_FORMAT_NONE;
345 else if (vis->mesa_visual.depthBits <= 16)
346 depthFormat = PIPE_FORMAT_Z16_UNORM;
347 else if (vis->mesa_visual.depthBits <= 24)
348 depthFormat = PIPE_FORMAT_S8Z24_UNORM;
349 else
350 depthFormat = PIPE_FORMAT_Z32_UNORM;
351
352 if (vis->mesa_visual.stencilBits == 8) {
353 if (depthFormat == PIPE_FORMAT_S8Z24_UNORM)
354 stencilFormat = depthFormat;
355 else
356 stencilFormat = PIPE_FORMAT_S8_UNORM;
357 }
358 else {
359 stencilFormat = PIPE_FORMAT_NONE;
360 }
361
362
Brianc6643022007-12-19 13:45:00 -0700363 get_drawable_size(vis->display, d, &width, &height);
364
Briane39f1b42007-11-05 15:59:55 -0700365 /*
366 * Create framebuffer, but we'll plug in our own renderbuffers below.
367 */
Brianc6643022007-12-19 13:45:00 -0700368 b->stfb = st_create_framebuffer(&vis->mesa_visual,
Brian20eae592007-12-12 14:55:57 -0700369 colorFormat, depthFormat, stencilFormat,
Brianc6643022007-12-19 13:45:00 -0700370 width, height,
Brian20eae592007-12-12 14:55:57 -0700371 (void *) b);
Briane39f1b42007-11-05 15:59:55 -0700372 fb = &b->stfb->Base;
373
Brianef25c492007-10-31 14:19:09 -0600374 /*
Brian749d7232007-12-07 07:57:54 -0700375 * Create scratch XImage for xmesa_display_surface()
Brianb7611772007-10-31 19:00:23 -0600376 */
Brian749d7232007-12-07 07:57:54 -0700377 b->tempImage = XCreateImage(vis->display,
378 vis->visinfo->visual,
379 vis->visinfo->depth,
380 ZPixmap, 0, /* format, offset */
381 NULL, /* data */
382 0, 0, /* size */
383 32, /* bitmap_pad */
384 0); /* bytes_per_line */
Brianef25c492007-10-31 14:19:09 -0600385
386 /* GLX_EXT_texture_from_pixmap */
387 b->TextureTarget = 0;
388 b->TextureFormat = GLX_TEXTURE_FORMAT_NONE_EXT;
389 b->TextureMipmap = 0;
390
391 /* insert buffer into linked list */
392 b->Next = XMesaBufferList;
393 XMesaBufferList = b;
394
395 return b;
396}
397
398
399/**
400 * Find an XMesaBuffer by matching X display and colormap but NOT matching
401 * the notThis buffer.
402 */
403XMesaBuffer
404xmesa_find_buffer(XMesaDisplay *dpy, XMesaColormap cmap, XMesaBuffer notThis)
405{
406 XMesaBuffer b;
Brian749d7232007-12-07 07:57:54 -0700407 for (b = XMesaBufferList; b; b = b->Next) {
408 if (b->xm_visual->display == dpy &&
409 b->cmap == cmap &&
410 b != notThis) {
Brianef25c492007-10-31 14:19:09 -0600411 return b;
412 }
413 }
414 return NULL;
415}
416
417
418/**
419 * Remove buffer from linked list, delete if no longer referenced.
420 */
421static void
422xmesa_free_buffer(XMesaBuffer buffer)
423{
424 XMesaBuffer prev = NULL, b;
425
426 for (b = XMesaBufferList; b; b = b->Next) {
427 if (b == buffer) {
Briane39f1b42007-11-05 15:59:55 -0700428 struct gl_framebuffer *fb = &buffer->stfb->Base;
Brianef25c492007-10-31 14:19:09 -0600429
430 /* unlink buffer from list */
431 if (prev)
432 prev->Next = buffer->Next;
433 else
434 XMesaBufferList = buffer->Next;
435
436 /* mark as delete pending */
437 fb->DeletePending = GL_TRUE;
438
439 /* Since the X window for the XMesaBuffer is going away, we don't
440 * want to dereference this pointer in the future.
441 */
Brian749d7232007-12-07 07:57:54 -0700442 b->drawable = 0;
443
444 buffer->tempImage->data = NULL;
445 XDestroyImage(buffer->tempImage);
Brianef25c492007-10-31 14:19:09 -0600446
447 /* Unreference. If count = zero we'll really delete the buffer */
448 _mesa_unreference_framebuffer(&fb);
449
Brianf44e2f12007-12-26 06:56:58 -0700450 XFreeGC(b->xm_visual->display, b->gc);
451
452 free(buffer);
453
Brianef25c492007-10-31 14:19:09 -0600454 return;
455 }
456 /* continue search */
457 prev = b;
458 }
459 /* buffer not found in XMesaBufferList */
460 _mesa_problem(NULL,"xmesa_free_buffer() - buffer not found\n");
461}
462
463
Brianef25c492007-10-31 14:19:09 -0600464
465/**********************************************************************/
466/***** Misc Private Functions *****/
467/**********************************************************************/
468
469
470/**
Brianef25c492007-10-31 14:19:09 -0600471 * When a context is bound for the first time, we can finally finish
472 * initializing the context's visual and buffer information.
473 * \param v the XMesaVisual to initialize
474 * \param b the XMesaBuffer to initialize (may be NULL)
475 * \param rgb_flag TRUE = RGBA mode, FALSE = color index mode
476 * \param window the window/pixmap we're rendering into
477 * \param cmap the colormap associated with the window/pixmap
478 * \return GL_TRUE=success, GL_FALSE=failure
479 */
480static GLboolean
481initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b,
482 GLboolean rgb_flag, XMesaDrawable window,
483 XMesaColormap cmap)
484{
Brianef25c492007-10-31 14:19:09 -0600485#ifdef XFree86Server
Brian749d7232007-12-07 07:57:54 -0700486 int client = (window) ? CLIENT_ID(window->id) : 0;
Brianef25c492007-10-31 14:19:09 -0600487#endif
488
489 ASSERT(!b || b->xm_visual == v);
490
491 /* Save true bits/pixel */
492 v->BitsPerPixel = bits_per_pixel(v);
493 assert(v->BitsPerPixel > 0);
494
495 if (rgb_flag == GL_FALSE) {
Brian749d7232007-12-07 07:57:54 -0700496 /* COLOR-INDEXED WINDOW: not supported*/
497 return GL_FALSE;
Brianef25c492007-10-31 14:19:09 -0600498 }
499 else {
500 /* RGB WINDOW:
501 * We support RGB rendering into almost any kind of visual.
502 */
503 const int xclass = v->mesa_visual.visualType;
Brian749d7232007-12-07 07:57:54 -0700504 if (xclass != GLX_TRUE_COLOR && xclass == !GLX_DIRECT_COLOR) {
505 _mesa_warning(NULL,
506 "XMesa: RGB mode rendering not supported in given visual.\n");
Brianef25c492007-10-31 14:19:09 -0600507 return GL_FALSE;
508 }
509 v->mesa_visual.indexBits = 0;
Brianef25c492007-10-31 14:19:09 -0600510 }
511
Brianef25c492007-10-31 14:19:09 -0600512 /*
513 * If MESA_INFO env var is set print out some debugging info
514 * which can help Brian figure out what's going on when a user
515 * reports bugs.
516 */
517 if (_mesa_getenv("MESA_INFO")) {
518 _mesa_printf("X/Mesa visual = %p\n", (void *) v);
Brianef25c492007-10-31 14:19:09 -0600519 _mesa_printf("X/Mesa level = %d\n", v->mesa_visual.level);
520 _mesa_printf("X/Mesa depth = %d\n", GET_VISUAL_DEPTH(v));
521 _mesa_printf("X/Mesa bits per pixel = %d\n", v->BitsPerPixel);
522 }
523
524 if (b && window) {
Brianef25c492007-10-31 14:19:09 -0600525 /* these should have been set in create_xmesa_buffer */
Brian749d7232007-12-07 07:57:54 -0700526 ASSERT(b->drawable == window);
Brianef25c492007-10-31 14:19:09 -0600527
528 /* Setup for single/double buffering */
529 if (v->mesa_visual.doubleBufferMode) {
530 /* Double buffered */
531 b->shm = check_for_xshm( v->display );
532 }
533
Brian749d7232007-12-07 07:57:54 -0700534 /* X11 graphics context */
Brianef25c492007-10-31 14:19:09 -0600535#ifdef XFree86Server
536 b->gc = CreateScratchGC(v->display, window->depth);
537#else
538 b->gc = XCreateGC( v->display, window, 0, NULL );
539#endif
540 XMesaSetFunction( v->display, b->gc, GXcopy );
Brianef25c492007-10-31 14:19:09 -0600541 }
542
543 return GL_TRUE;
544}
545
546
547
Brianef25c492007-10-31 14:19:09 -0600548#define NUM_VISUAL_TYPES 6
549
550/**
551 * Convert an X visual type to a GLX visual type.
552 *
553 * \param visualType X visual type (i.e., \c TrueColor, \c StaticGray, etc.)
554 * to be converted.
555 * \return If \c visualType is a valid X visual type, a GLX visual type will
556 * be returned. Otherwise \c GLX_NONE will be returned.
557 *
558 * \note
559 * This code was lifted directly from lib/GL/glx/glcontextmodes.c in the
560 * DRI CVS tree.
561 */
562static GLint
563xmesa_convert_from_x_visual_type( int visualType )
564{
565 static const int glx_visual_types[ NUM_VISUAL_TYPES ] = {
566 GLX_STATIC_GRAY, GLX_GRAY_SCALE,
567 GLX_STATIC_COLOR, GLX_PSEUDO_COLOR,
568 GLX_TRUE_COLOR, GLX_DIRECT_COLOR
569 };
570
571 return ( (unsigned) visualType < NUM_VISUAL_TYPES )
572 ? glx_visual_types[ visualType ] : GLX_NONE;
573}
574
575
576/**********************************************************************/
577/***** Public Functions *****/
578/**********************************************************************/
579
580
581/*
582 * Create a new X/Mesa visual.
583 * Input: display - X11 display
584 * visinfo - an XVisualInfo pointer
585 * rgb_flag - GL_TRUE = RGB mode,
586 * GL_FALSE = color index mode
587 * alpha_flag - alpha buffer requested?
588 * db_flag - GL_TRUE = double-buffered,
589 * GL_FALSE = single buffered
590 * stereo_flag - stereo visual?
591 * ximage_flag - GL_TRUE = use an XImage for back buffer,
592 * GL_FALSE = use an off-screen pixmap for back buffer
593 * depth_size - requested bits/depth values, or zero
594 * stencil_size - requested bits/stencil values, or zero
595 * accum_red_size - requested bits/red accum values, or zero
596 * accum_green_size - requested bits/green accum values, or zero
597 * accum_blue_size - requested bits/blue accum values, or zero
598 * accum_alpha_size - requested bits/alpha accum values, or zero
599 * num_samples - number of samples/pixel if multisampling, or zero
600 * level - visual level, usually 0
601 * visualCaveat - ala the GLX extension, usually GLX_NONE
602 * Return; a new XMesaVisual or 0 if error.
603 */
604PUBLIC
605XMesaVisual XMesaCreateVisual( XMesaDisplay *display,
606 XMesaVisualInfo visinfo,
607 GLboolean rgb_flag,
608 GLboolean alpha_flag,
609 GLboolean db_flag,
610 GLboolean stereo_flag,
611 GLboolean ximage_flag,
612 GLint depth_size,
613 GLint stencil_size,
614 GLint accum_red_size,
615 GLint accum_green_size,
616 GLint accum_blue_size,
617 GLint accum_alpha_size,
618 GLint num_samples,
619 GLint level,
620 GLint visualCaveat )
621{
Brianef25c492007-10-31 14:19:09 -0600622 XMesaVisual v;
623 GLint red_bits, green_bits, blue_bits, alpha_bits;
624
625#ifndef XFree86Server
626 /* For debugging only */
627 if (_mesa_getenv("MESA_XSYNC")) {
628 /* This makes debugging X easier.
629 * In your debugger, set a breakpoint on _XError to stop when an
630 * X protocol error is generated.
631 */
632 XSynchronize( display, 1 );
633 }
634#endif
635
636 v = (XMesaVisual) CALLOC_STRUCT(xmesa_visual);
637 if (!v) {
638 return NULL;
639 }
640
641 v->display = display;
642
643 /* Save a copy of the XVisualInfo struct because the user may X_mesa_free()
644 * the struct but we may need some of the information contained in it
645 * at a later time.
646 */
647#ifndef XFree86Server
648 v->visinfo = (XVisualInfo *) MALLOC(sizeof(*visinfo));
649 if(!v->visinfo) {
650 _mesa_free(v);
651 return NULL;
652 }
653 MEMCPY(v->visinfo, visinfo, sizeof(*visinfo));
654#endif
655
Brianef25c492007-10-31 14:19:09 -0600656 v->ximage_flag = ximage_flag;
657
658#ifdef XFree86Server
659 /* We could calculate these values by ourselves. nplanes is either the sum
660 * of the red, green, and blue bits or the number index bits.
661 * ColormapEntries is either (1U << index_bits) or
662 * (1U << max(redBits, greenBits, blueBits)).
663 */
664 assert(visinfo->nplanes > 0);
665 v->nplanes = visinfo->nplanes;
666 v->ColormapEntries = visinfo->ColormapEntries;
667
668 v->mesa_visual.redMask = visinfo->redMask;
669 v->mesa_visual.greenMask = visinfo->greenMask;
670 v->mesa_visual.blueMask = visinfo->blueMask;
671 v->mesa_visual.visualID = visinfo->vid;
672 v->mesa_visual.screen = 0; /* FIXME: What should be done here? */
673#else
674 v->mesa_visual.redMask = visinfo->red_mask;
675 v->mesa_visual.greenMask = visinfo->green_mask;
676 v->mesa_visual.blueMask = visinfo->blue_mask;
677 v->mesa_visual.visualID = visinfo->visualid;
678 v->mesa_visual.screen = visinfo->screen;
679#endif
680
681#if defined(XFree86Server) || !(defined(__cplusplus) || defined(c_plusplus))
682 v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->class);
683#else
684 v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->c_class);
685#endif
686
687 v->mesa_visual.visualRating = visualCaveat;
688
689 if (alpha_flag)
690 v->mesa_visual.alphaBits = 8;
691
692 (void) initialize_visual_and_buffer( v, NULL, rgb_flag, 0, 0 );
693
694 {
695 const int xclass = v->mesa_visual.visualType;
696 if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) {
697 red_bits = _mesa_bitcount(GET_REDMASK(v));
698 green_bits = _mesa_bitcount(GET_GREENMASK(v));
699 blue_bits = _mesa_bitcount(GET_BLUEMASK(v));
700 }
701 else {
702 /* this is an approximation */
703 int depth;
704 depth = GET_VISUAL_DEPTH(v);
705 red_bits = depth / 3;
706 depth -= red_bits;
707 green_bits = depth / 2;
708 depth -= green_bits;
709 blue_bits = depth;
710 alpha_bits = 0;
711 assert( red_bits + green_bits + blue_bits == GET_VISUAL_DEPTH(v) );
712 }
713 alpha_bits = v->mesa_visual.alphaBits;
714 }
715
716 _mesa_initialize_visual( &v->mesa_visual,
717 rgb_flag, db_flag, stereo_flag,
718 red_bits, green_bits,
719 blue_bits, alpha_bits,
720 v->mesa_visual.indexBits,
721 depth_size,
722 stencil_size,
723 accum_red_size, accum_green_size,
724 accum_blue_size, accum_alpha_size,
725 0 );
726
727 /* XXX minor hack */
728 v->mesa_visual.level = level;
729 return v;
730}
731
732
733PUBLIC
734void XMesaDestroyVisual( XMesaVisual v )
735{
736#ifndef XFree86Server
737 _mesa_free(v->visinfo);
738#endif
739 _mesa_free(v);
740}
741
742
743
744/**
745 * Create a new XMesaContext.
746 * \param v the XMesaVisual
747 * \param share_list another XMesaContext with which to share display
748 * lists or NULL if no sharing is wanted.
749 * \return an XMesaContext or NULL if error.
750 */
751PUBLIC
752XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
753{
754 static GLboolean firstTime = GL_TRUE;
Briane39f1b42007-11-05 15:59:55 -0700755 struct pipe_context *pipe;
Brianef25c492007-10-31 14:19:09 -0600756 XMesaContext c;
757 GLcontext *mesaCtx;
Brian749d7232007-12-07 07:57:54 -0700758 uint pf;
Briane39f1b42007-11-05 15:59:55 -0700759
Brianef25c492007-10-31 14:19:09 -0600760 if (firstTime) {
761 _glthread_INIT_MUTEX(_xmesa_lock);
762 firstTime = GL_FALSE;
763 }
764
765 /* Note: the XMesaContext contains a Mesa GLcontext struct (inheritance) */
766 c = (XMesaContext) CALLOC_STRUCT(xmesa_context);
767 if (!c)
768 return NULL;
769
Brian749d7232007-12-07 07:57:54 -0700770 pf = choose_pixel_format(v);
Brian0d1669f2007-12-07 08:24:56 -0700771 assert(pf);
Brian749d7232007-12-07 07:57:54 -0700772
Zack Rusinc474f1f2007-12-11 07:19:11 -0500773 if (!getenv("XM_AUB")) {
774 xmesa_mode = XMESA_SOFTPIPE;
775 pipe = xmesa_create_pipe_context( c, pf );
776 }
777 else {
778 xmesa_mode = XMESA_AUB;
779 pipe = xmesa_create_i965simple( xmesa_get_pipe_winsys_aub() );
780 }
Brianef25c492007-10-31 14:19:09 -0600781
Brian91564ee2007-11-05 16:15:43 -0700782 c->st = st_create_context(pipe, &v->mesa_visual,
783 share_list ? share_list->st : NULL);
Briane39f1b42007-11-05 15:59:55 -0700784 mesaCtx = c->st->ctx;
785 c->st->ctx->DriverCtx = c;
Brianef25c492007-10-31 14:19:09 -0600786
Briane39f1b42007-11-05 15:59:55 -0700787#if 00
Brianef25c492007-10-31 14:19:09 -0600788 _mesa_enable_sw_extensions(mesaCtx);
789 _mesa_enable_1_3_extensions(mesaCtx);
790 _mesa_enable_1_4_extensions(mesaCtx);
791 _mesa_enable_1_5_extensions(mesaCtx);
792 _mesa_enable_2_0_extensions(mesaCtx);
Briane39f1b42007-11-05 15:59:55 -0700793#endif
Brianef25c492007-10-31 14:19:09 -0600794
795#ifdef XFree86Server
796 /* If we're running in the X server, do bounds checking to prevent
797 * segfaults and server crashes!
798 */
799 mesaCtx->Const.CheckArrayBounds = GL_TRUE;
800#endif
801
802 /* finish up xmesa context initializations */
Brianef25c492007-10-31 14:19:09 -0600803 c->xm_visual = v;
804 c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */
Brianef25c492007-10-31 14:19:09 -0600805
Brian749d7232007-12-07 07:57:54 -0700806 c->st->haveFramebufferSurfaces = GL_TRUE;
Brianef25c492007-10-31 14:19:09 -0600807
808 return c;
809}
810
811
812
813PUBLIC
814void XMesaDestroyContext( XMesaContext c )
815{
Brian91564ee2007-11-05 16:15:43 -0700816 st_destroy_context(c->st);
Briane39f1b42007-11-05 15:59:55 -0700817 _mesa_free(c);
Brianef25c492007-10-31 14:19:09 -0600818}
819
820
821
822/**
823 * Private function for creating an XMesaBuffer which corresponds to an
824 * X window or pixmap.
825 * \param v the window's XMesaVisual
826 * \param w the window we're wrapping
827 * \return new XMesaBuffer or NULL if error
828 */
829PUBLIC XMesaBuffer
830XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w)
831{
832#ifndef XFree86Server
833 XWindowAttributes attr;
834#endif
835 XMesaBuffer b;
836 XMesaColormap cmap;
837 int depth;
838
839 assert(v);
840 assert(w);
841
842 /* Check that window depth matches visual depth */
843#ifdef XFree86Server
844 depth = ((XMesaDrawable)w)->depth;
845#else
846 XGetWindowAttributes( v->display, w, &attr );
847 depth = attr.depth;
848#endif
849 if (GET_VISUAL_DEPTH(v) != depth) {
850 _mesa_warning(NULL, "XMesaCreateWindowBuffer: depth mismatch between visual (%d) and window (%d)!\n",
851 GET_VISUAL_DEPTH(v), depth);
852 return NULL;
853 }
854
855 /* Find colormap */
856#ifdef XFree86Server
857 cmap = (ColormapPtr)LookupIDByType(wColormap(w), RT_COLORMAP);
858#else
859 if (attr.colormap) {
860 cmap = attr.colormap;
861 }
862 else {
863 _mesa_warning(NULL, "Window %u has no colormap!\n", (unsigned int) w);
864 /* this is weird, a window w/out a colormap!? */
865 /* OK, let's just allocate a new one and hope for the best */
866 cmap = XCreateColormap(v->display, w, attr.visual, AllocNone);
867 }
868#endif
869
870 b = create_xmesa_buffer((XMesaDrawable) w, WINDOW, v, cmap);
871 if (!b)
872 return NULL;
873
874 if (!initialize_visual_and_buffer( v, b, v->mesa_visual.rgbMode,
875 (XMesaDrawable) w, cmap )) {
876 xmesa_free_buffer(b);
877 return NULL;
878 }
879
880 return b;
881}
882
883
884
885/**
886 * Create a new XMesaBuffer from an X pixmap.
887 *
888 * \param v the XMesaVisual
889 * \param p the pixmap
890 * \param cmap the colormap, may be 0 if using a \c GLX_TRUE_COLOR or
891 * \c GLX_DIRECT_COLOR visual for the pixmap
892 * \returns new XMesaBuffer or NULL if error
893 */
894PUBLIC XMesaBuffer
895XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p, XMesaColormap cmap)
896{
897 XMesaBuffer b;
898
899 assert(v);
900
901 b = create_xmesa_buffer((XMesaDrawable) p, PIXMAP, v, cmap);
902 if (!b)
903 return NULL;
904
905 if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode,
906 (XMesaDrawable) p, cmap)) {
907 xmesa_free_buffer(b);
908 return NULL;
909 }
910
911 return b;
912}
913
914
915/**
916 * For GLX_EXT_texture_from_pixmap
917 */
918XMesaBuffer
919XMesaCreatePixmapTextureBuffer(XMesaVisual v, XMesaPixmap p,
920 XMesaColormap cmap,
921 int format, int target, int mipmap)
922{
923 GET_CURRENT_CONTEXT(ctx);
924 XMesaBuffer b;
925 GLuint width, height;
926
927 assert(v);
928
929 b = create_xmesa_buffer((XMesaDrawable) p, PIXMAP, v, cmap);
930 if (!b)
931 return NULL;
932
933 /* get pixmap size, update framebuffer/renderbuffer dims */
934 xmesa_get_window_size(v->display, b, &width, &height);
Briane39f1b42007-11-05 15:59:55 -0700935 _mesa_resize_framebuffer(NULL, &(b->stfb->Base), width, height);
Brianef25c492007-10-31 14:19:09 -0600936
937 if (target == 0) {
938 /* examine dims */
939 if (ctx->Extensions.ARB_texture_non_power_of_two) {
940 target = GLX_TEXTURE_2D_EXT;
941 }
942 else if ( _mesa_bitcount(width) == 1
943 && _mesa_bitcount(height) == 1) {
944 /* power of two size */
945 if (height == 1) {
946 target = GLX_TEXTURE_1D_EXT;
947 }
948 else {
949 target = GLX_TEXTURE_2D_EXT;
950 }
951 }
952 else if (ctx->Extensions.NV_texture_rectangle) {
953 target = GLX_TEXTURE_RECTANGLE_EXT;
954 }
955 else {
956 /* non power of two textures not supported */
957 XMesaDestroyBuffer(b);
958 return 0;
959 }
960 }
961
962 b->TextureTarget = target;
963 b->TextureFormat = format;
964 b->TextureMipmap = mipmap;
965
966 if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode,
967 (XMesaDrawable) p, cmap)) {
968 xmesa_free_buffer(b);
969 return NULL;
970 }
971
972 return b;
973}
974
975
976
977XMesaBuffer
978XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap,
979 unsigned int width, unsigned int height)
980{
981#ifndef XFree86Server
982 XMesaWindow root;
983 XMesaDrawable drawable; /* X Pixmap Drawable */
984 XMesaBuffer b;
985
986 /* allocate pixmap for front buffer */
987 root = RootWindow( v->display, v->visinfo->screen );
988 drawable = XCreatePixmap(v->display, root, width, height,
989 v->visinfo->depth);
990 if (!drawable)
991 return NULL;
992
993 b = create_xmesa_buffer(drawable, PBUFFER, v, cmap);
994 if (!b)
995 return NULL;
996
997 if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode,
998 drawable, cmap)) {
999 xmesa_free_buffer(b);
1000 return NULL;
1001 }
1002
1003 return b;
1004#else
1005 return 0;
1006#endif
1007}
1008
1009
1010
1011/*
1012 * Deallocate an XMesaBuffer structure and all related info.
1013 */
1014PUBLIC void
1015XMesaDestroyBuffer(XMesaBuffer b)
1016{
1017 xmesa_free_buffer(b);
1018}
1019
1020
1021/**
1022 * Query the current window size and update the corresponding GLframebuffer
1023 * and all attached renderbuffers.
1024 * Called when:
1025 * 1. the first time a buffer is bound to a context.
Brian749d7232007-12-07 07:57:54 -07001026 * 2. from the XMesaResizeBuffers() API function.
1027 * 3. SwapBuffers. XXX probabaly from xm_flush_frontbuffer() too...
Brianef25c492007-10-31 14:19:09 -06001028 * Note: it's possible (and legal) for xmctx to be NULL. That can happen
1029 * when resizing a buffer when no rendering context is bound.
1030 */
1031void
1032xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer)
1033{
1034 GLuint width, height;
Brian749d7232007-12-07 07:57:54 -07001035 xmesa_get_window_size(drawBuffer->xm_visual->display, drawBuffer, &width, &height);
Briane39f1b42007-11-05 15:59:55 -07001036 st_resize_framebuffer(drawBuffer->stfb, width, height);
Brianef25c492007-10-31 14:19:09 -06001037}
1038
1039
1040/*
1041 * Bind buffer b to context c and make c the current rendering context.
1042 */
1043GLboolean XMesaMakeCurrent( XMesaContext c, XMesaBuffer b )
1044{
1045 return XMesaMakeCurrent2( c, b, b );
1046}
1047
1048
1049/*
1050 * Bind buffer b to context c and make c the current rendering context.
1051 */
1052PUBLIC
1053GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer,
1054 XMesaBuffer readBuffer )
1055{
1056 if (c) {
1057 if (!drawBuffer || !readBuffer)
1058 return GL_FALSE; /* must specify buffers! */
1059
Briane39f1b42007-11-05 15:59:55 -07001060#if 0
1061 /* XXX restore this optimization */
Brianef25c492007-10-31 14:19:09 -06001062 if (&(c->mesa) == _mesa_get_current_context()
1063 && c->mesa.DrawBuffer == &drawBuffer->mesa_buffer
1064 && c->mesa.ReadBuffer == &readBuffer->mesa_buffer
Brian749d7232007-12-07 07:57:54 -07001065 && xmesa_buffer(c->mesa.DrawBuffer)->wasCurrent) {
Brianef25c492007-10-31 14:19:09 -06001066 /* same context and buffer, do nothing */
1067 return GL_TRUE;
1068 }
Briane39f1b42007-11-05 15:59:55 -07001069#endif
Brianef25c492007-10-31 14:19:09 -06001070
1071 c->xm_buffer = drawBuffer;
1072
Brianef25c492007-10-31 14:19:09 -06001073 /* Call this periodically to detect when the user has begun using
1074 * GL rendering from multiple threads.
1075 */
1076 _glapi_check_multithread();
1077
Briandbf6ece2007-12-19 08:50:35 -07001078 st_make_current(c->st, drawBuffer->stfb, readBuffer->stfb);
1079
Brianef25c492007-10-31 14:19:09 -06001080 xmesa_check_and_update_buffer_size(c, drawBuffer);
1081 if (readBuffer != drawBuffer)
1082 xmesa_check_and_update_buffer_size(c, readBuffer);
1083
Brianef25c492007-10-31 14:19:09 -06001084 /* Solution to Stephane Rehel's problem with glXReleaseBuffersMESA(): */
1085 drawBuffer->wasCurrent = GL_TRUE;
1086 }
1087 else {
1088 /* Detach */
Briane39f1b42007-11-05 15:59:55 -07001089 st_make_current( NULL, NULL, NULL );
Brianef25c492007-10-31 14:19:09 -06001090 }
1091 return GL_TRUE;
1092}
1093
1094
1095/*
1096 * Unbind the context c from its buffer.
1097 */
1098GLboolean XMesaUnbindContext( XMesaContext c )
1099{
1100 /* A no-op for XFree86 integration purposes */
1101 return GL_TRUE;
1102}
1103
1104
1105XMesaContext XMesaGetCurrentContext( void )
1106{
1107 GET_CURRENT_CONTEXT(ctx);
1108 if (ctx) {
Brian749d7232007-12-07 07:57:54 -07001109 XMesaContext xmesa = xmesa_context(ctx);
Brianef25c492007-10-31 14:19:09 -06001110 return xmesa;
1111 }
1112 else {
1113 return 0;
1114 }
1115}
1116
1117
1118XMesaBuffer XMesaGetCurrentBuffer( void )
1119{
1120 GET_CURRENT_CONTEXT(ctx);
1121 if (ctx) {
Brian749d7232007-12-07 07:57:54 -07001122 XMesaBuffer xmbuf = xmesa_buffer(ctx->DrawBuffer);
Brianef25c492007-10-31 14:19:09 -06001123 return xmbuf;
1124 }
1125 else {
1126 return 0;
1127 }
1128}
1129
1130
1131/* New in Mesa 3.1 */
1132XMesaBuffer XMesaGetCurrentReadBuffer( void )
1133{
1134 GET_CURRENT_CONTEXT(ctx);
1135 if (ctx) {
Brian749d7232007-12-07 07:57:54 -07001136 return xmesa_buffer(ctx->ReadBuffer);
Brianef25c492007-10-31 14:19:09 -06001137 }
1138 else {
1139 return 0;
1140 }
1141}
1142
1143
1144#ifdef XFree86Server
1145PUBLIC
1146GLboolean XMesaForceCurrent(XMesaContext c)
1147{
1148 if (c) {
1149 _glapi_set_dispatch(c->mesa.CurrentDispatch);
1150
1151 if (&(c->mesa) != _mesa_get_current_context()) {
1152 _mesa_make_current(&c->mesa, c->mesa.DrawBuffer, c->mesa.ReadBuffer);
1153 }
1154 }
1155 else {
1156 _mesa_make_current(NULL, NULL, NULL);
1157 }
1158 return GL_TRUE;
1159}
1160
1161
1162PUBLIC
1163GLboolean XMesaLoseCurrent(XMesaContext c)
1164{
1165 (void) c;
1166 _mesa_make_current(NULL, NULL, NULL);
1167 return GL_TRUE;
1168}
1169
1170
1171PUBLIC
1172GLboolean XMesaCopyContext( XMesaContext xm_src, XMesaContext xm_dst, GLuint mask )
1173{
1174 _mesa_copy_context(&xm_src->mesa, &xm_dst->mesa, mask);
1175 return GL_TRUE;
1176}
1177#endif /* XFree86Server */
1178
1179
1180#ifndef FX
1181GLboolean XMesaSetFXmode( GLint mode )
1182{
1183 (void) mode;
1184 return GL_FALSE;
1185}
1186#endif
1187
1188
1189
1190/*
1191 * Copy the back buffer to the front buffer. If there's no back buffer
1192 * this is a no-op.
1193 */
1194PUBLIC
1195void XMesaSwapBuffers( XMesaBuffer b )
1196{
Brian749d7232007-12-07 07:57:54 -07001197 struct pipe_surface *surf;
Brianef25c492007-10-31 14:19:09 -06001198
1199 /* If we're swapping the buffer associated with the current context
1200 * we have to flush any pending rendering commands first.
1201 */
Briane39f1b42007-11-05 15:59:55 -07001202 st_notify_swapbuffers(b->stfb);
Brianef25c492007-10-31 14:19:09 -06001203
Brian749d7232007-12-07 07:57:54 -07001204 surf = st_get_framebuffer_surface(b->stfb, ST_SURFACE_BACK_LEFT);
1205 if (surf) {
Zack Rusinc474f1f2007-12-11 07:19:11 -05001206 if (xmesa_mode == XMESA_AUB)
1207 xmesa_display_aub( surf );
1208 else
1209 xmesa_display_surface(b, surf);
Brianef25c492007-10-31 14:19:09 -06001210 }
Brian749d7232007-12-07 07:57:54 -07001211
1212 xmesa_check_and_update_buffer_size(NULL, b);
Brianef25c492007-10-31 14:19:09 -06001213}
1214
1215
1216
1217/*
1218 * Copy sub-region of back buffer to front buffer
1219 */
1220void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height )
1221{
Brian749d7232007-12-07 07:57:54 -07001222 struct pipe_surface *surf_front
1223 = st_get_framebuffer_surface(b->stfb, ST_SURFACE_FRONT_LEFT);
1224 struct pipe_surface *surf_back
1225 = st_get_framebuffer_surface(b->stfb, ST_SURFACE_BACK_LEFT);
1226 struct pipe_context *pipe = NULL; /* XXX fix */
Brianef25c492007-10-31 14:19:09 -06001227
Brian749d7232007-12-07 07:57:54 -07001228 if (!surf_front || !surf_back)
1229 return;
Briane39f1b42007-11-05 15:59:55 -07001230
Brian749d7232007-12-07 07:57:54 -07001231 pipe->surface_copy(pipe,
Michel Dänzere922adb2008-02-13 11:39:58 +00001232 FALSE,
Brian749d7232007-12-07 07:57:54 -07001233 surf_front, x, y, /* dest */
1234 surf_back, x, y, /* src */
1235 width, height);
Brianef25c492007-10-31 14:19:09 -06001236}
1237
1238
Brianef25c492007-10-31 14:19:09 -06001239
1240/*
1241 * Return the depth buffer associated with an XMesaBuffer.
1242 * Input: b - the XMesa buffer handle
1243 * Output: width, height - size of buffer in pixels
1244 * bytesPerValue - bytes per depth value (2 or 4)
1245 * buffer - pointer to depth buffer values
1246 * Return: GL_TRUE or GL_FALSE to indicate success or failure.
1247 */
1248GLboolean XMesaGetDepthBuffer( XMesaBuffer b, GLint *width, GLint *height,
1249 GLint *bytesPerValue, void **buffer )
1250{
Michel Dänzerc76efb92008-01-10 17:44:04 +01001251 *width = 0;
1252 *height = 0;
1253 *bytesPerValue = 0;
1254 *buffer = 0;
1255 return GL_FALSE;
Brianef25c492007-10-31 14:19:09 -06001256}
1257
1258
1259void XMesaFlush( XMesaContext c )
1260{
Brian749d7232007-12-07 07:57:54 -07001261 if (c && c->xm_visual->display) {
Brianef25c492007-10-31 14:19:09 -06001262#ifdef XFree86Server
1263 /* NOT_NEEDED */
1264#else
Brian749d7232007-12-07 07:57:54 -07001265 XSync( c->xm_visual->display, False );
Brianef25c492007-10-31 14:19:09 -06001266#endif
1267 }
1268}
1269
1270
1271
1272const char *XMesaGetString( XMesaContext c, int name )
1273{
1274 (void) c;
1275 if (name==XMESA_VERSION) {
1276 return "5.0";
1277 }
1278 else if (name==XMESA_EXTENSIONS) {
1279 return "";
1280 }
1281 else {
1282 return NULL;
1283 }
1284}
1285
1286
1287
1288XMesaBuffer XMesaFindBuffer( XMesaDisplay *dpy, XMesaDrawable d )
1289{
1290 XMesaBuffer b;
1291 for (b=XMesaBufferList; b; b=b->Next) {
Brian749d7232007-12-07 07:57:54 -07001292 if (b->drawable == d && b->xm_visual->display == dpy) {
Brianef25c492007-10-31 14:19:09 -06001293 return b;
1294 }
1295 }
1296 return NULL;
1297}
1298
1299
1300/**
1301 * Free/destroy all XMesaBuffers associated with given display.
1302 */
1303void xmesa_destroy_buffers_on_display(XMesaDisplay *dpy)
1304{
1305 XMesaBuffer b, next;
1306 for (b = XMesaBufferList; b; b = next) {
1307 next = b->Next;
Brian749d7232007-12-07 07:57:54 -07001308 if (b->xm_visual->display == dpy) {
Brianef25c492007-10-31 14:19:09 -06001309 xmesa_free_buffer(b);
1310 }
1311 }
1312}
1313
1314
1315/*
1316 * Look for XMesaBuffers whose X window has been destroyed.
1317 * Deallocate any such XMesaBuffers.
1318 */
1319void XMesaGarbageCollect( void )
1320{
1321 XMesaBuffer b, next;
1322 for (b=XMesaBufferList; b; b=next) {
1323 next = b->Next;
Brian749d7232007-12-07 07:57:54 -07001324 if (b->xm_visual &&
1325 b->xm_visual->display &&
1326 b->drawable &&
1327 b->type == WINDOW) {
Brianef25c492007-10-31 14:19:09 -06001328#ifdef XFree86Server
1329 /* NOT_NEEDED */
1330#else
Brian749d7232007-12-07 07:57:54 -07001331 XSync(b->xm_visual->display, False);
1332 if (!window_exists( b->xm_visual->display, b->drawable )) {
Brianef25c492007-10-31 14:19:09 -06001333 /* found a dead window, free the ancillary info */
1334 XMesaDestroyBuffer( b );
1335 }
1336#endif
1337 }
1338 }
1339}
1340
1341
1342unsigned long XMesaDitherColor( XMesaContext xmesa, GLint x, GLint y,
1343 GLfloat red, GLfloat green,
1344 GLfloat blue, GLfloat alpha )
1345{
Brian749d7232007-12-07 07:57:54 -07001346 /* no longer supported */
Brianef25c492007-10-31 14:19:09 -06001347 return 0;
1348}
1349
1350
1351/*
1352 * This is typically called when the window size changes and we need
1353 * to reallocate the buffer's back/depth/stencil/accum buffers.
1354 */
1355PUBLIC void
1356XMesaResizeBuffers( XMesaBuffer b )
1357{
1358 GET_CURRENT_CONTEXT(ctx);
Brian749d7232007-12-07 07:57:54 -07001359 XMesaContext xmctx = xmesa_context(ctx);
Brianef25c492007-10-31 14:19:09 -06001360 if (!xmctx)
1361 return;
1362 xmesa_check_and_update_buffer_size(xmctx, b);
1363}
1364
1365
Brianef25c492007-10-31 14:19:09 -06001366
1367
1368PUBLIC void
1369XMesaBindTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer,
1370 const int *attrib_list)
1371{
Brianef25c492007-10-31 14:19:09 -06001372}
1373
1374
1375
1376PUBLIC void
1377XMesaReleaseTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer)
1378{
Brianef25c492007-10-31 14:19:09 -06001379}
1380