1 /* $XFree86: xc/lib/GL/glx/glxcmds.c,v 1.30 2004/01/30 20:33:06 alanh Exp $ */
3 ** License Applicability. Except to the extent portions of this file are
4 ** made subject to an alternative license as permitted in the SGI Free
5 ** Software License B, Version 1.1 (the "License"), the contents of this
6 ** file are subject only to the provisions of the License. You may not use
7 ** this file except in compliance with the License. You may obtain a copy
8 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
9 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
11 ** http://oss.sgi.com/projects/FreeB
13 ** Note that, as provided in the License, the Software is distributed on an
14 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
15 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
16 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
17 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
19 ** Original Code. The Original Code is: OpenGL Sample Implementation,
20 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
21 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
22 ** Copyright in any portions created by third parties is as indicated
23 ** elsewhere herein. All Rights Reserved.
25 ** Additional Notice Provisions: The application programming interfaces
26 ** established by SGI in conjunction with the Original Code are The
27 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
28 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
29 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
30 ** Window System(R) (Version 1.3), released October 19, 1998. This software
31 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
32 ** published by SGI, but has not been independently verified as being
33 ** compliant with the OpenGL(R) version 1.2.1 Specification.
39 * Client-side GLX interface.
43 #include "glxclient.h"
49 #ifdef GLX_DIRECT_RENDERING
50 #include "indirect_init.h"
51 #include "xf86vmode.h"
53 #include "glxextensions.h"
54 #include "glcontextmodes.h"
59 #define GLX_PREFIX(x) x
60 #endif /* IN_DOXYGEN */
62 static const char __glXGLXClientVendorName
[] = "SGI";
63 static const char __glXGLXClientVersion
[] = "1.4";
66 #if defined(GLX_DIRECT_RENDERING)
69 static Bool
__glXWindowExists(Display
*dpy
, GLXDrawable draw
);
71 static void * DriverCreateContextWrapper( const __GLXscreenConfigs
*psc
,
72 Display
*dpy
, XVisualInfo
*vis
, void *shared
, __DRIcontext
*ctx
,
73 const __GLcontextModes
*fbconfig
, int render_type
);
75 #ifndef DRI_NEW_INTERFACE_ONLY
76 static Bool
dummyBindContext2( Display
*dpy
, int scrn
,
77 GLXDrawable draw
, GLXDrawable read
, GLXContext gc
);
79 static Bool
dummyUnbindContext2( Display
*dpy
, int scrn
,
80 GLXDrawable draw
, GLXDrawable read
, GLXContext gc
);
82 /****************************************************************************/
85 * Used as glue when a driver does not support
86 * \c __DRIcontextRec::bindContext2.
88 * XXX .bindContext is only defined as a function pointer if
89 * !DRI_NEW_INTERFACE_ONLY.
91 * \sa DriverCreateContextWrapper, __DRIcontextRec::bindContext2
93 static Bool
dummyBindContext2( Display
*dpy
, int scrn
,
94 GLXDrawable draw
, GLXDrawable read
,
97 assert( draw
== read
);
98 return (*gc
->driContext
.bindContext
)( dpy
, scrn
, draw
, gc
);
102 * Used as glue when a driver does not support
103 * \c __DRIcontextRec::unbindContext2.
105 * XXX .unbindContext is only defined as a function pointer if
106 * !DRI_NEW_INTERFACE_ONLY.
108 * \sa DriverCreateContextWrapper, __DRIcontextRec::unbindContext2
110 static Bool
dummyUnbindContext2( Display
*dpy
, int scrn
,
111 GLXDrawable draw
, GLXDrawable read
,
114 assert( draw
== read
);
115 return (*gc
->driContext
.unbindContext
)( dpy
, scrn
, draw
, gc
, GL_FALSE
);
117 #endif /* DRI_NEW_INTERFACE_ONLY */
120 /****************************************************************************/
122 * Wrap the call to the driver's \c createContext function.
124 * The \c createContext function is wrapped because not all drivers support
125 * the "new" \c unbindContext2 and \c bindContext2 interfaces. libGL should
126 * not have to check to see which functions the driver supports. Instead,
127 * if either function is not supported it is wrapped. The wrappers test to
128 * make sure that both drawables are the same and pass control to the old
131 * \sa dummyBindContext2, dummyUnbindContext2,
132 * __DRIcontextRec::bindContext2, __DRIcontextRec::unbindContext2
135 static void * DriverCreateContextWrapper( const __GLXscreenConfigs
*psc
,
136 Display
*dpy
, XVisualInfo
*vis
,
139 const __GLcontextModes
*modes
,
142 void * ctx_priv
= NULL
;
144 if ( psc
->driScreen
.createNewContext
!= NULL
) {
145 assert( modes
!= NULL
);
146 ctx_priv
= (*psc
->driScreen
.createNewContext
)(dpy
, modes
, render_type
,
149 /* If the driver supports the createNewContext interface, then
150 * it MUST also support either the bindContext2 / unbindContext2
151 * interface or the bindContext3 / unbindContext3 interface.
154 assert( (ctx_priv
== NULL
) || (ctx
->unbindContext2
!= NULL
)
155 || (ctx
->unbindContext3
!= NULL
) );
156 assert( (ctx_priv
== NULL
) || (ctx
->bindContext2
!= NULL
)
157 || (ctx
->bindContext3
!= NULL
) );
159 #ifndef DRI_NEW_INTERFACE_ONLY
162 ctx_priv
= (*psc
->driScreen
.createContext
)(dpy
, vis
, shared
, ctx
);
164 if ( ctx_priv
!= NULL
) {
165 if ( ctx
->unbindContext2
== NULL
) {
166 ctx
->unbindContext2
= dummyUnbindContext2
;
169 if ( ctx
->bindContext2
== NULL
) {
170 ctx
->bindContext2
= dummyBindContext2
;
182 /****************************************************************************/
184 * Get the __DRIdrawable for the drawable associated with a GLXContext
186 * \param dpy The display associated with \c drawable.
187 * \param drawable GLXDrawable whose __DRIdrawable part is to be retrieved.
188 * \returns A pointer to the context's __DRIdrawable on success, or NULL if
189 * the drawable is not associated with a direct-rendering context.
192 #ifdef GLX_DIRECT_RENDERING
193 static __DRIdrawable
*
194 GetDRIDrawable( Display
*dpy
, GLXDrawable drawable
, int * const scrn_num
)
196 __GLXdisplayPrivate
* const priv
= __glXInitialize(dpy
);
198 if ( (priv
!= NULL
) && (priv
->driDisplay
.private != NULL
) ) {
199 const unsigned screen_count
= ScreenCount(dpy
);
202 for ( i
= 0 ; i
< screen_count
; i
++ ) {
203 __DRIscreen
* const psc
= &priv
->screenConfigs
[i
].driScreen
;
204 __DRIdrawable
* const pdraw
= (psc
->private != NULL
)
205 ? (*psc
->getDrawable
)(dpy
, drawable
, psc
->private) : NULL
;
207 if ( pdraw
!= NULL
) {
208 if ( scrn_num
!= NULL
) {
222 * Get the GLX per-screen data structure associated with a GLX context.
224 * \param dpy Display for which the GLX per-screen information is to be
226 * \param scrn Screen on \c dpy for which the GLX per-screen information is
228 * \returns A pointer to the GLX per-screen data if \c dpy and \c scrn
229 * specify a valid GLX screen, or NULL otherwise.
231 * \todo Should this function validate that \c scrn is within the screen
232 * number range for \c dpy?
235 static __GLXscreenConfigs
*
236 GetGLXScreenConfigs(Display
*dpy
, int scrn
)
238 __GLXdisplayPrivate
* const priv
= __glXInitialize(dpy
);
240 return (priv
->screenConfigs
!= NULL
) ? &priv
->screenConfigs
[scrn
] : NULL
;
245 GetGLXPrivScreenConfig( Display
*dpy
, int scrn
, __GLXdisplayPrivate
** ppriv
,
246 __GLXscreenConfigs
** ppsc
)
248 /* Initialize the extension, if needed . This has the added value
249 * of initializing/allocating the display private
253 return GLX_NO_EXTENSION
;
256 *ppriv
= __glXInitialize(dpy
);
257 if ( *ppriv
== NULL
) {
258 return GLX_NO_EXTENSION
;
261 /* Check screen number to see if its valid */
262 if ((scrn
< 0) || (scrn
>= ScreenCount(dpy
))) {
263 return GLX_BAD_SCREEN
;
266 /* Check to see if the GL is supported on this screen */
267 *ppsc
= &((*ppriv
)->screenConfigs
[scrn
]);
268 if ( (*ppsc
)->configs
== NULL
) {
269 /* No support for GL on this screen regardless of visual */
270 return GLX_BAD_VISUAL
;
278 * Determine if a \c GLXFBConfig supplied by the application is valid.
280 * \param dpy Application supplied \c Display pointer.
281 * \param config Application supplied \c GLXFBConfig.
283 * \returns If the \c GLXFBConfig is valid, the a pointer to the matching
284 * \c __GLcontextModes structure is returned. Otherwise, \c NULL
287 static __GLcontextModes
*
288 ValidateGLXFBConfig( Display
* dpy
, GLXFBConfig config
)
290 __GLXdisplayPrivate
* const priv
= __glXInitialize(dpy
);
291 const unsigned num_screens
= ScreenCount(dpy
);
293 const __GLcontextModes
* modes
;
296 if ( priv
!= NULL
) {
297 for ( i
= 0 ; i
< num_screens
; i
++ ) {
298 for ( modes
= priv
->screenConfigs
[i
].configs
300 ; modes
= modes
->next
) {
301 if ( modes
== (__GLcontextModes
*) config
) {
302 return (__GLcontextModes
*) config
;
313 * \todo It should be possible to move the allocate of \c client_state_private
314 * later in the function for direct-rendering contexts. Direct-rendering
315 * contexts don't need to track client state, so they don't need that memory
318 * \todo Eliminate \c __glXInitVertexArrayState. Replace it with a new
319 * function called \c __glXAllocateClientState that allocates the memory and
320 * does all the initialization (including the pixel pack / unpack).
323 GLXContext
AllocateGLXContext( Display
*dpy
)
328 __GLXattribute
*state
;
333 opcode
= __glXSetupForCommand(dpy
);
338 /* Allocate our context record */
339 gc
= (GLXContext
) Xmalloc(sizeof(struct __GLXcontextRec
));
344 memset(gc
, 0, sizeof(struct __GLXcontextRec
));
346 state
= Xmalloc(sizeof(struct __GLXattributeRec
));
352 gc
->client_state_private
= state
;
353 memset(gc
->client_state_private
, 0, sizeof(struct __GLXattributeRec
));
354 state
->NoDrawArraysProtocol
= (getenv("LIBGL_NO_DRAWARRAYS") != NULL
);
357 ** Create a temporary buffer to hold GLX rendering commands. The size
358 ** of the buffer is selected so that the maximum number of GLX rendering
359 ** commands can fit in a single X packet and still have room in the X
360 ** packet for the GLXRenderReq header.
363 bufSize
= (XMaxRequestSize(dpy
) * 4) - sz_xGLXRenderReq
;
364 gc
->buf
= (GLubyte
*) Xmalloc(bufSize
);
366 Xfree(gc
->client_state_private
);
370 gc
->bufSize
= bufSize
;
372 /* Fill in the new context */
373 gc
->renderMode
= GL_RENDER
;
375 state
->storePack
.alignment
= 4;
376 state
->storeUnpack
.alignment
= 4;
378 gc
->attributes
.stackPointer
= &gc
->attributes
.stack
[0];
381 ** PERFORMANCE NOTE: A mode dependent fill image can speed things up.
382 ** Other code uses the fastImageUnpack bit, but it is never set
385 gc
->fastImageUnpack
= GL_FALSE
;
386 gc
->fillImage
= __glFillImage
;
387 gc
->isDirect
= GL_FALSE
;
389 gc
->bufEnd
= gc
->buf
+ bufSize
;
392 ** Set limit register so that there will be one command per packet
396 gc
->limit
= gc
->buf
+ bufSize
- __GLX_BUFFER_LIMIT_SIZE
;
399 gc
->majorOpcode
= opcode
;
402 ** Constrain the maximum drawing command size allowed to be
403 ** transfered using the X_GLXRender protocol request. First
404 ** constrain by a software limit, then constrain by the protocl
407 if (bufSize
> __GLX_RENDER_CMD_SIZE_LIMIT
) {
408 bufSize
= __GLX_RENDER_CMD_SIZE_LIMIT
;
410 if (bufSize
> __GLX_MAX_RENDER_CMD_SIZE
) {
411 bufSize
= __GLX_MAX_RENDER_CMD_SIZE
;
413 gc
->maxSmallRenderCommandSize
= bufSize
;
419 * Create a new context. Exactly one of \c vis and \c fbconfig should be
422 * \param use_glx_1_3 For FBConfigs, should GLX 1.3 protocol or
423 * SGIX_fbconfig protocol be used?
424 * \param renderType For FBConfigs, what is the rendering type?
428 CreateContext(Display
*dpy
, XVisualInfo
*vis
,
429 const __GLcontextModes
* const fbconfig
,
430 GLXContext shareList
,
431 Bool allowDirect
, GLXContextID contextID
,
432 Bool use_glx_1_3
, int renderType
)
439 gc
= AllocateGLXContext(dpy
);
443 if (None
== contextID
) {
444 if ( (vis
== NULL
) && (fbconfig
== NULL
) )
447 #ifdef GLX_DIRECT_RENDERING
449 int screen
= (fbconfig
== NULL
) ? vis
->screen
: fbconfig
->screen
;
450 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs(dpy
, screen
);
451 const __GLcontextModes
* mode
;
453 /* The value of fbconfig cannot change because it is tested
454 * later in the function.
456 if ( fbconfig
== NULL
) {
457 /* FIXME: Is it possible for the __GLcontextModes structure
458 * FIXME: to not be found?
460 mode
= _gl_context_modes_find_visual( psc
->configs
,
462 assert( mode
!= NULL
);
463 assert( mode
->screen
== screen
);
469 if (psc
&& psc
->driScreen
.private) {
470 void * const shared
= (shareList
!= NULL
)
471 ? shareList
->driContext
.private : NULL
;
472 gc
->driContext
.private =
473 DriverCreateContextWrapper( psc
, dpy
, vis
, shared
,
474 &gc
->driContext
, mode
,
476 if (gc
->driContext
.private) {
477 gc
->isDirect
= GL_TRUE
;
478 gc
->screen
= mode
->screen
;
479 gc
->vid
= mode
->visualID
;
480 gc
->fbconfigID
= mode
->fbconfigID
;
481 gc
->driContext
.mode
= mode
;
488 if ( fbconfig
== NULL
) {
489 xGLXCreateContextReq
*req
;
491 /* Send the glXCreateContext request */
492 GetReq(GLXCreateContext
,req
);
493 req
->reqType
= gc
->majorOpcode
;
494 req
->glxCode
= X_GLXCreateContext
;
495 req
->context
= gc
->xid
= XAllocID(dpy
);
496 req
->visual
= vis
->visualid
;
497 req
->screen
= vis
->screen
;
498 req
->shareList
= shareList
? shareList
->xid
: None
;
499 req
->isDirect
= gc
->isDirect
;
501 else if ( use_glx_1_3
) {
502 xGLXCreateNewContextReq
*req
;
504 /* Send the glXCreateNewContext request */
505 GetReq(GLXCreateNewContext
,req
);
506 req
->reqType
= gc
->majorOpcode
;
507 req
->glxCode
= X_GLXCreateNewContext
;
508 req
->context
= gc
->xid
= XAllocID(dpy
);
509 req
->fbconfig
= fbconfig
->fbconfigID
;
510 req
->screen
= fbconfig
->screen
;
511 req
->renderType
= renderType
;
512 req
->shareList
= shareList
? shareList
->xid
: None
;
513 req
->isDirect
= gc
->isDirect
;
516 xGLXVendorPrivateWithReplyReq
*vpreq
;
517 xGLXCreateContextWithConfigSGIXReq
*req
;
519 /* Send the glXCreateNewContext request */
520 GetReqExtra(GLXVendorPrivateWithReply
,
521 sz_xGLXCreateContextWithConfigSGIXReq
-sz_xGLXVendorPrivateWithReplyReq
,vpreq
);
522 req
= (xGLXCreateContextWithConfigSGIXReq
*)vpreq
;
523 req
->reqType
= gc
->majorOpcode
;
524 req
->glxCode
= X_GLXVendorPrivateWithReply
;
525 req
->vendorCode
= X_GLXvop_CreateContextWithConfigSGIX
;
526 req
->context
= gc
->xid
= XAllocID(dpy
);
527 req
->fbconfig
= fbconfig
->fbconfigID
;
528 req
->screen
= fbconfig
->screen
;
529 req
->renderType
= renderType
;
530 req
->shareList
= shareList
? shareList
->xid
: None
;
531 req
->isDirect
= gc
->isDirect
;
536 gc
->imported
= GL_FALSE
;
540 gc
->imported
= GL_TRUE
;
546 PUBLIC GLXContext
GLX_PREFIX(glXCreateContext
)(Display
*dpy
, XVisualInfo
*vis
,
547 GLXContext shareList
,
550 return CreateContext(dpy
, vis
, NULL
, shareList
, allowDirect
, None
,
554 void __glXFreeContext(__GLXcontext
*gc
)
556 if (gc
->vendor
) XFree((char *) gc
->vendor
);
557 if (gc
->renderer
) XFree((char *) gc
->renderer
);
558 if (gc
->version
) XFree((char *) gc
->version
);
559 if (gc
->extensions
) XFree((char *) gc
->extensions
);
560 __glFreeAttributeState(gc
);
561 XFree((char *) gc
->buf
);
562 Xfree((char *) gc
->client_state_private
);
568 ** Destroy the named context
571 DestroyContext(Display
*dpy
, GLXContext gc
)
573 xGLXDestroyContextReq
*req
;
578 opcode
= __glXSetupForCommand(dpy
);
579 if (!opcode
|| !gc
) {
585 imported
= gc
->imported
;
588 #ifdef GLX_DIRECT_RENDERING
589 /* Destroy the direct rendering context */
591 if (gc
->driContext
.private) {
592 (*gc
->driContext
.destroyContext
)(dpy
, gc
->screen
,
593 gc
->driContext
.private);
594 gc
->driContext
.private = NULL
;
599 if (gc
->currentDpy
) {
600 /* Have to free later cuz it's in use now */
603 /* Destroy the handle if not current to anybody */
605 __glXFreeContext(gc
);
610 ** This dpy also created the server side part of the context.
611 ** Send the glXDestroyContext request.
614 GetReq(GLXDestroyContext
,req
);
615 req
->reqType
= opcode
;
616 req
->glxCode
= X_GLXDestroyContext
;
623 PUBLIC
void GLX_PREFIX(glXDestroyContext
)(Display
*dpy
, GLXContext gc
)
625 DestroyContext(dpy
, gc
);
629 ** Return the major and minor version #s for the GLX extension
631 PUBLIC Bool
GLX_PREFIX(glXQueryVersion
)(Display
*dpy
, int *major
, int *minor
)
633 __GLXdisplayPrivate
*priv
;
635 /* Init the extension. This fetches the major and minor version. */
636 priv
= __glXInitialize(dpy
);
637 if (!priv
) return GL_FALSE
;
639 if (major
) *major
= priv
->majorVersion
;
640 if (minor
) *minor
= priv
->minorVersion
;
645 ** Query the existance of the GLX extension
647 PUBLIC Bool
GLX_PREFIX(glXQueryExtension
)(Display
*dpy
, int *errorBase
,
650 int major_op
, erb
, evb
;
653 rv
= XQueryExtension(dpy
, GLX_EXTENSION_NAME
, &major_op
, &evb
, &erb
);
655 if (errorBase
) *errorBase
= erb
;
656 if (eventBase
) *eventBase
= evb
;
662 ** Put a barrier in the token stream that forces the GL to finish its
663 ** work before X can proceed.
665 PUBLIC
void GLX_PREFIX(glXWaitGL
)(void)
668 GLXContext gc
= __glXGetCurrentContext();
669 Display
*dpy
= gc
->currentDpy
;
673 /* Flush any pending commands out */
674 __glXFlushRenderBuffer(gc
, gc
->pc
);
676 #ifdef GLX_DIRECT_RENDERING
678 /* This bit of ugliness unwraps the glFinish function */
687 /* Send the glXWaitGL request */
689 GetReq(GLXWaitGL
,req
);
690 req
->reqType
= gc
->majorOpcode
;
691 req
->glxCode
= X_GLXWaitGL
;
692 req
->contextTag
= gc
->currentContextTag
;
698 ** Put a barrier in the token stream that forces X to finish its
699 ** work before GL can proceed.
701 PUBLIC
void GLX_PREFIX(glXWaitX
)(void)
704 GLXContext gc
= __glXGetCurrentContext();
705 Display
*dpy
= gc
->currentDpy
;
709 /* Flush any pending commands out */
710 __glXFlushRenderBuffer(gc
, gc
->pc
);
712 #ifdef GLX_DIRECT_RENDERING
720 ** Send the glXWaitX request.
723 GetReq(GLXWaitX
,req
);
724 req
->reqType
= gc
->majorOpcode
;
725 req
->glxCode
= X_GLXWaitX
;
726 req
->contextTag
= gc
->currentContextTag
;
731 PUBLIC
void GLX_PREFIX(glXUseXFont
)(Font font
, int first
, int count
,
734 xGLXUseXFontReq
*req
;
735 GLXContext gc
= __glXGetCurrentContext();
736 Display
*dpy
= gc
->currentDpy
;
740 /* Flush any pending commands out */
741 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
743 #ifdef GLX_DIRECT_RENDERING
745 DRI_glXUseXFont(font
, first
, count
, listBase
);
750 /* Send the glXUseFont request */
752 GetReq(GLXUseXFont
,req
);
753 req
->reqType
= gc
->majorOpcode
;
754 req
->glxCode
= X_GLXUseXFont
;
755 req
->contextTag
= gc
->currentContextTag
;
759 req
->listBase
= listBase
;
764 /************************************************************************/
767 ** Copy the source context to the destination context using the
770 PUBLIC
void GLX_PREFIX(glXCopyContext
)(Display
*dpy
, GLXContext source
,
771 GLXContext dest
, unsigned long mask
)
773 xGLXCopyContextReq
*req
;
774 GLXContext gc
= __glXGetCurrentContext();
778 opcode
= __glXSetupForCommand(dpy
);
783 #ifdef GLX_DIRECT_RENDERING
785 /* NOT_DONE: This does not work yet */
790 ** If the source is the current context, send its tag so that the context
791 ** can be flushed before the copy.
793 if (source
== gc
&& dpy
== gc
->currentDpy
) {
794 tag
= gc
->currentContextTag
;
799 /* Send the glXCopyContext request */
801 GetReq(GLXCopyContext
,req
);
802 req
->reqType
= opcode
;
803 req
->glxCode
= X_GLXCopyContext
;
804 req
->source
= source
? source
->xid
: None
;
805 req
->dest
= dest
? dest
->xid
: None
;
807 req
->contextTag
= tag
;
814 * Determine if a context uses direct rendering.
816 * \param dpy Display where the context was created.
817 * \param contextID ID of the context to be tested.
819 * \returns \c GL_TRUE if the context is direct rendering or not.
821 static Bool
__glXIsDirect(Display
*dpy
, GLXContextID contextID
)
823 xGLXIsDirectReq
*req
;
824 xGLXIsDirectReply reply
;
827 opcode
= __glXSetupForCommand(dpy
);
832 /* Send the glXIsDirect request */
834 GetReq(GLXIsDirect
,req
);
835 req
->reqType
= opcode
;
836 req
->glxCode
= X_GLXIsDirect
;
837 req
->context
= contextID
;
838 _XReply(dpy
, (xReply
*) &reply
, 0, False
);
842 return reply
.isDirect
;
845 PUBLIC Bool
GLX_PREFIX(glXIsDirect
)(Display
*dpy
, GLXContext gc
)
849 #ifdef GLX_DIRECT_RENDERING
850 } else if (gc
->isDirect
) {
854 return __glXIsDirect(dpy
, gc
->xid
);
857 PUBLIC GLXPixmap
GLX_PREFIX(glXCreateGLXPixmap
)(Display
*dpy
, XVisualInfo
*vis
,
860 xGLXCreateGLXPixmapReq
*req
;
864 opcode
= __glXSetupForCommand(dpy
);
869 /* Send the glXCreateGLXPixmap request */
871 GetReq(GLXCreateGLXPixmap
,req
);
872 req
->reqType
= opcode
;
873 req
->glxCode
= X_GLXCreateGLXPixmap
;
874 req
->screen
= vis
->screen
;
875 req
->visual
= vis
->visualid
;
876 req
->pixmap
= pixmap
;
877 req
->glxpixmap
= xid
= XAllocID(dpy
);
884 ** Destroy the named pixmap
886 PUBLIC
void GLX_PREFIX(glXDestroyGLXPixmap
)(Display
*dpy
, GLXPixmap glxpixmap
)
888 xGLXDestroyGLXPixmapReq
*req
;
891 opcode
= __glXSetupForCommand(dpy
);
896 /* Send the glXDestroyGLXPixmap request */
898 GetReq(GLXDestroyGLXPixmap
,req
);
899 req
->reqType
= opcode
;
900 req
->glxCode
= X_GLXDestroyGLXPixmap
;
901 req
->glxpixmap
= glxpixmap
;
906 PUBLIC
void GLX_PREFIX(glXSwapBuffers
)(Display
*dpy
, GLXDrawable drawable
)
908 xGLXSwapBuffersReq
*req
;
912 #ifdef GLX_DIRECT_RENDERING
913 __DRIdrawable
*pdraw
= GetDRIDrawable( dpy
, drawable
, NULL
);
915 if ( pdraw
!= NULL
) {
916 (*pdraw
->swapBuffers
)(dpy
, pdraw
->private);
921 opcode
= __glXSetupForCommand(dpy
);
927 ** The calling thread may or may not have a current context. If it
928 ** does, send the context tag so the server can do a flush.
930 gc
= __glXGetCurrentContext();
931 if ((gc
!= NULL
) && (dpy
== gc
->currentDpy
) &&
932 ((drawable
== gc
->currentDrawable
) || (drawable
== gc
->currentReadable
)) ) {
933 tag
= gc
->currentContextTag
;
938 /* Send the glXSwapBuffers request */
940 GetReq(GLXSwapBuffers
,req
);
941 req
->reqType
= opcode
;
942 req
->glxCode
= X_GLXSwapBuffers
;
943 req
->drawable
= drawable
;
944 req
->contextTag
= tag
;
952 ** Return configuration information for the given display, screen and
953 ** visual combination.
955 PUBLIC
int GLX_PREFIX(glXGetConfig
)(Display
*dpy
, XVisualInfo
*vis
,
956 int attribute
, int *value_return
)
958 __GLXdisplayPrivate
*priv
;
959 __GLXscreenConfigs
*psc
;
962 status
= GetGLXPrivScreenConfig( dpy
, vis
->screen
, & priv
, & psc
);
963 if ( status
== Success
) {
964 const __GLcontextModes
* const modes
= _gl_context_modes_find_visual(
965 psc
->configs
, vis
->visualid
);
967 /* Lookup attribute after first finding a match on the visual */
968 if ( modes
!= NULL
) {
969 return _gl_get_context_mode_data( modes
, attribute
, value_return
);
972 status
= GLX_BAD_VISUAL
;
976 ** If we can't find the config for this visual, this visual is not
977 ** supported by the OpenGL implementation on the server.
979 if ( (status
== GLX_BAD_VISUAL
) && (attribute
== GLX_USE_GL
) ) {
980 *value_return
= GL_FALSE
;
987 /************************************************************************/
990 init_fbconfig_for_chooser( __GLcontextModes
* config
,
991 GLboolean fbconfig_style_tags
)
993 memset( config
, 0, sizeof( __GLcontextModes
) );
994 config
->visualID
= (XID
) GLX_DONT_CARE
;
995 config
->visualType
= GLX_DONT_CARE
;
997 /* glXChooseFBConfig specifies different defaults for these two than
1000 if ( fbconfig_style_tags
) {
1001 config
->rgbMode
= GL_TRUE
;
1002 config
->doubleBufferMode
= GLX_DONT_CARE
;
1005 config
->visualRating
= GLX_DONT_CARE
;
1006 config
->transparentPixel
= GLX_NONE
;
1007 config
->transparentRed
= GLX_DONT_CARE
;
1008 config
->transparentGreen
= GLX_DONT_CARE
;
1009 config
->transparentBlue
= GLX_DONT_CARE
;
1010 config
->transparentAlpha
= GLX_DONT_CARE
;
1011 config
->transparentIndex
= GLX_DONT_CARE
;
1013 config
->drawableType
= GLX_WINDOW_BIT
;
1014 config
->renderType
= (config
->rgbMode
) ? GLX_RGBA_BIT
: GLX_COLOR_INDEX_BIT
;
1015 config
->xRenderable
= GLX_DONT_CARE
;
1016 config
->fbconfigID
= (GLXFBConfigID
)(GLX_DONT_CARE
);
1018 config
->swapMethod
= GLX_DONT_CARE
;
1021 #define MATCH_DONT_CARE( param ) \
1023 if ( (a-> param != GLX_DONT_CARE) \
1024 && (a-> param != b-> param) ) { \
1029 #define MATCH_MINIMUM( param ) \
1031 if ( (a-> param != GLX_DONT_CARE) \
1032 && (a-> param > b-> param) ) { \
1037 #define MATCH_EXACT( param ) \
1039 if ( a-> param != b-> param) { \
1045 * Determine if two GLXFBConfigs are compatible.
1047 * \param a Application specified config to test.
1048 * \param b Server specified config to test against \c a.
1051 fbconfigs_compatible( const __GLcontextModes
* const a
,
1052 const __GLcontextModes
* const b
)
1054 MATCH_DONT_CARE( doubleBufferMode
);
1055 MATCH_DONT_CARE( visualType
);
1056 MATCH_DONT_CARE( visualRating
);
1057 MATCH_DONT_CARE( xRenderable
);
1058 MATCH_DONT_CARE( fbconfigID
);
1059 MATCH_DONT_CARE( swapMethod
);
1061 MATCH_MINIMUM( rgbBits
);
1062 MATCH_MINIMUM( numAuxBuffers
);
1063 MATCH_MINIMUM( redBits
);
1064 MATCH_MINIMUM( greenBits
);
1065 MATCH_MINIMUM( blueBits
);
1066 MATCH_MINIMUM( alphaBits
);
1067 MATCH_MINIMUM( depthBits
);
1068 MATCH_MINIMUM( stencilBits
);
1069 MATCH_MINIMUM( accumRedBits
);
1070 MATCH_MINIMUM( accumGreenBits
);
1071 MATCH_MINIMUM( accumBlueBits
);
1072 MATCH_MINIMUM( accumAlphaBits
);
1073 MATCH_MINIMUM( sampleBuffers
);
1074 MATCH_MINIMUM( maxPbufferWidth
);
1075 MATCH_MINIMUM( maxPbufferHeight
);
1076 MATCH_MINIMUM( maxPbufferPixels
);
1077 MATCH_MINIMUM( samples
);
1079 MATCH_DONT_CARE( stereoMode
);
1080 MATCH_EXACT( level
);
1082 if ( ((a
->drawableType
& b
->drawableType
) == 0)
1083 || ((a
->renderType
& b
->renderType
) == 0) ) {
1088 /* There is a bug in a few of the XFree86 DDX drivers. They contain
1089 * visuals with a "transparent type" of 0 when they really mean GLX_NONE.
1090 * Technically speaking, it is a bug in the DDX driver, but there is
1091 * enough of an installed base to work around the problem here. In any
1092 * case, 0 is not a valid value of the transparent type, so we'll treat 0
1093 * from the app as GLX_DONT_CARE. We'll consider GLX_NONE from the app and
1094 * 0 from the server to be a match to maintain backward compatibility with
1095 * the (broken) drivers.
1098 if ( a
->transparentPixel
!= GLX_DONT_CARE
1099 && a
->transparentPixel
!= 0 ) {
1100 if ( a
->transparentPixel
== GLX_NONE
) {
1101 if ( b
->transparentPixel
!= GLX_NONE
&& b
->transparentPixel
!= 0 )
1104 MATCH_EXACT( transparentPixel
);
1107 switch ( a
->transparentPixel
) {
1108 case GLX_TRANSPARENT_RGB
:
1109 MATCH_DONT_CARE( transparentRed
);
1110 MATCH_DONT_CARE( transparentGreen
);
1111 MATCH_DONT_CARE( transparentBlue
);
1112 MATCH_DONT_CARE( transparentAlpha
);
1115 case GLX_TRANSPARENT_INDEX
:
1116 MATCH_DONT_CARE( transparentIndex
);
1128 /* There's some trickly language in the GLX spec about how this is supposed
1129 * to work. Basically, if a given component size is either not specified
1130 * or the requested size is zero, it is supposed to act like PERFER_SMALLER.
1131 * Well, that's really hard to do with the code as-is. This behavior is
1132 * closer to correct, but still not technically right.
1134 #define PREFER_LARGER_OR_ZERO(comp) \
1136 if ( ((*a)-> comp) != ((*b)-> comp) ) { \
1137 if ( ((*a)-> comp) == 0 ) { \
1140 else if ( ((*b)-> comp) == 0 ) { \
1144 return ((*b)-> comp) - ((*a)-> comp) ; \
1149 #define PREFER_LARGER(comp) \
1151 if ( ((*a)-> comp) != ((*b)-> comp) ) { \
1152 return ((*b)-> comp) - ((*a)-> comp) ; \
1156 #define PREFER_SMALLER(comp) \
1158 if ( ((*a)-> comp) != ((*b)-> comp) ) { \
1159 return ((*a)-> comp) - ((*b)-> comp) ; \
1164 * Compare two GLXFBConfigs. This function is intended to be used as the
1165 * compare function passed in to qsort.
1167 * \returns If \c a is a "better" config, according to the specification of
1168 * SGIX_fbconfig, a number less than zero is returned. If \c b is
1169 * better, then a number greater than zero is return. If both are
1170 * equal, zero is returned.
1171 * \sa qsort, glXChooseVisual, glXChooseFBConfig, glXChooseFBConfigSGIX
1174 fbconfig_compare( const __GLcontextModes
* const * const a
,
1175 const __GLcontextModes
* const * const b
)
1177 /* The order of these comparisons must NOT change. It is defined by
1178 * the GLX 1.3 spec and ARB_multisample.
1181 PREFER_SMALLER( visualSelectGroup
);
1183 /* The sort order for the visualRating is GLX_NONE, GLX_SLOW, and
1184 * GLX_NON_CONFORMANT_CONFIG. It just so happens that this is the
1185 * numerical sort order of the enums (0x8000, 0x8001, and 0x800D).
1187 PREFER_SMALLER( visualRating
);
1189 /* This isn't quite right. It is supposed to compare the sum of the
1190 * components the user specifically set minimums for.
1192 PREFER_LARGER_OR_ZERO( redBits
);
1193 PREFER_LARGER_OR_ZERO( greenBits
);
1194 PREFER_LARGER_OR_ZERO( blueBits
);
1195 PREFER_LARGER_OR_ZERO( alphaBits
);
1197 PREFER_SMALLER( rgbBits
);
1199 if ( ((*a
)->doubleBufferMode
!= (*b
)->doubleBufferMode
) ) {
1200 /* Prefer single-buffer.
1202 return ( !(*a
)->doubleBufferMode
) ? -1 : 1;
1205 PREFER_SMALLER( numAuxBuffers
);
1207 PREFER_LARGER_OR_ZERO( depthBits
);
1208 PREFER_SMALLER( stencilBits
);
1210 /* This isn't quite right. It is supposed to compare the sum of the
1211 * components the user specifically set minimums for.
1213 PREFER_LARGER_OR_ZERO( accumRedBits
);
1214 PREFER_LARGER_OR_ZERO( accumGreenBits
);
1215 PREFER_LARGER_OR_ZERO( accumBlueBits
);
1216 PREFER_LARGER_OR_ZERO( accumAlphaBits
);
1218 PREFER_SMALLER( visualType
);
1220 /* None of the multisample specs say where this comparison should happen,
1221 * so I put it near the end.
1223 PREFER_SMALLER( sampleBuffers
);
1224 PREFER_SMALLER( samples
);
1226 /* None of the pbuffer or fbconfig specs say that this comparison needs
1227 * to happen at all, but it seems like it should.
1229 PREFER_LARGER( maxPbufferWidth
);
1230 PREFER_LARGER( maxPbufferHeight
);
1231 PREFER_LARGER( maxPbufferPixels
);
1238 * Selects and sorts a subset of the supplied configs based on the attributes.
1239 * This function forms to basis of \c glXChooseVisual, \c glXChooseFBConfig,
1240 * and \c glXChooseFBConfigSGIX.
1242 * \param configs Array of pointers to possible configs. The elements of
1243 * this array that do not meet the criteria will be set to
1244 * NULL. The remaining elements will be sorted according to
1245 * the various visual / FBConfig selection rules.
1246 * \param num_configs Number of elements in the \c configs array.
1247 * \param attribList Attributes used select from \c configs. This array is
1248 * terminated by a \c None tag. The array can either take
1249 * the form expected by \c glXChooseVisual (where boolean
1250 * tags do not have a value) or by \c glXChooseFBConfig
1251 * (where every tag has a value).
1252 * \param fbconfig_style_tags Selects whether \c attribList is in
1253 * \c glXChooseVisual style or
1254 * \c glXChooseFBConfig style.
1255 * \returns The number of valid elements left in \c configs.
1257 * \sa glXChooseVisual, glXChooseFBConfig, glXChooseFBConfigSGIX
1260 choose_visual( __GLcontextModes
** configs
, int num_configs
,
1261 const int *attribList
, GLboolean fbconfig_style_tags
)
1263 __GLcontextModes test_config
;
1267 /* This is a fairly direct implementation of the selection method
1268 * described by GLX_SGIX_fbconfig. Start by culling out all the
1269 * configs that are not compatible with the selected parameter
1273 init_fbconfig_for_chooser( & test_config
, fbconfig_style_tags
);
1274 __glXInitializeVisualConfigFromTags( & test_config
, 512,
1275 (const INT32
*) attribList
,
1276 GL_TRUE
, fbconfig_style_tags
);
1279 for ( i
= 0 ; i
< num_configs
; i
++ ) {
1280 if ( fbconfigs_compatible( & test_config
, configs
[i
] ) ) {
1281 configs
[ base
] = configs
[ i
];
1290 if ( base
< num_configs
) {
1291 (void) memset( & configs
[ base
], 0,
1292 sizeof( void * ) * (num_configs
- base
) );
1295 /* After the incompatible configs are removed, the resulting
1296 * list is sorted according to the rules set out in the various
1300 qsort( configs
, base
, sizeof( __GLcontextModes
* ),
1301 (int (*)(const void*, const void*)) fbconfig_compare
);
1309 ** Return the visual that best matches the template. Return None if no
1310 ** visual matches the template.
1312 PUBLIC XVisualInfo
*GLX_PREFIX(glXChooseVisual
)(Display
*dpy
, int screen
,
1315 XVisualInfo
*visualList
= NULL
;
1316 __GLXdisplayPrivate
*priv
;
1317 __GLXscreenConfigs
*psc
;
1318 __GLcontextModes test_config
;
1319 __GLcontextModes
*modes
;
1320 const __GLcontextModes
*best_config
= NULL
;
1323 ** Get a list of all visuals, return if list is empty
1325 if ( GetGLXPrivScreenConfig( dpy
, screen
, & priv
, & psc
) != Success
) {
1331 ** Build a template from the defaults and the attribute list
1332 ** Free visual list and return if an unexpected token is encountered
1334 init_fbconfig_for_chooser( & test_config
, GL_FALSE
);
1335 __glXInitializeVisualConfigFromTags( & test_config
, 512,
1336 (const INT32
*) attribList
,
1337 GL_TRUE
, GL_FALSE
);
1340 ** Eliminate visuals that don't meet minimum requirements
1341 ** Compute a score for those that do
1342 ** Remember which visual, if any, got the highest score
1344 for ( modes
= psc
->configs
; modes
!= NULL
; modes
= modes
->next
) {
1345 if ( fbconfigs_compatible( & test_config
, modes
)
1346 && ((best_config
== NULL
)
1347 || (fbconfig_compare( (const __GLcontextModes
* const * const)&modes
, &best_config
) < 0)) ) {
1348 best_config
= modes
;
1353 ** If no visual is acceptable, return None
1354 ** Otherwise, create an XVisualInfo list with just the selected X visual
1357 if (best_config
!= NULL
) {
1358 XVisualInfo visualTemplate
;
1361 visualTemplate
.screen
= screen
;
1362 visualTemplate
.visualid
= best_config
->visualID
;
1363 visualList
= XGetVisualInfo( dpy
, VisualScreenMask
|VisualIDMask
,
1364 &visualTemplate
, &i
);
1371 PUBLIC
const char *GLX_PREFIX(glXQueryExtensionsString
)( Display
*dpy
,
1374 __GLXscreenConfigs
*psc
;
1375 __GLXdisplayPrivate
*priv
;
1377 if ( GetGLXPrivScreenConfig( dpy
, screen
, & priv
, & psc
) != Success
) {
1381 if (!psc
->effectiveGLXexts
) {
1382 if (!psc
->serverGLXexts
) {
1383 psc
->serverGLXexts
= __glXGetStringFromServer(dpy
, priv
->majorOpcode
,
1384 X_GLXQueryServerString
,
1385 screen
, GLX_EXTENSIONS
);
1388 __glXCalculateUsableExtensions(psc
,
1389 #ifdef GLX_DIRECT_RENDERING
1390 (priv
->driDisplay
.private != NULL
),
1394 priv
->minorVersion
);
1397 return psc
->effectiveGLXexts
;
1400 PUBLIC
const char *GLX_PREFIX(glXGetClientString
)( Display
*dpy
, int name
)
1404 return (__glXGLXClientVendorName
);
1406 return (__glXGLXClientVersion
);
1407 case GLX_EXTENSIONS
:
1408 return (__glXGetClientExtensions());
1414 PUBLIC
const char *GLX_PREFIX(glXQueryServerString
)( Display
*dpy
, int screen
,
1417 __GLXscreenConfigs
*psc
;
1418 __GLXdisplayPrivate
*priv
;
1422 if ( GetGLXPrivScreenConfig( dpy
, screen
, & priv
, & psc
) != Success
) {
1428 str
= & priv
->serverGLXvendor
;
1431 str
= & priv
->serverGLXversion
;
1433 case GLX_EXTENSIONS
:
1434 str
= & psc
->serverGLXexts
;
1440 if ( *str
== NULL
) {
1441 *str
= __glXGetStringFromServer(dpy
, priv
->majorOpcode
,
1442 X_GLXQueryServerString
, screen
, name
);
1448 void __glXClientInfo ( Display
*dpy
, int opcode
)
1450 xGLXClientInfoReq
*req
;
1452 char * ext_str
= __glXGetClientGLExtensionString();
1454 /* Send the glXClientInfo request */
1456 GetReq(GLXClientInfo
,req
);
1457 req
->reqType
= opcode
;
1458 req
->glxCode
= X_GLXClientInfo
;
1459 req
->major
= GLX_MAJOR_VERSION
;
1460 req
->minor
= GLX_MINOR_VERSION
;
1462 size
= strlen( ext_str
) + 1;
1463 req
->length
+= (size
+ 3) >> 2;
1464 req
->numbytes
= size
;
1465 Data(dpy
, ext_str
, size
);
1475 ** EXT_import_context
1478 PUBLIC Display
*glXGetCurrentDisplay(void)
1480 GLXContext gc
= __glXGetCurrentContext();
1481 if (NULL
== gc
) return NULL
;
1482 return gc
->currentDpy
;
1485 PUBLIC
GLX_ALIAS(Display
*, glXGetCurrentDisplayEXT
, (void), (),
1486 glXGetCurrentDisplay
)
1489 * Used internally by libGL to send \c xGLXQueryContextinfoExtReq requests
1492 * \param dpy Display where \c ctx was created.
1493 * \param ctx Context to query.
1494 * \returns \c Success on success. \c GLX_BAD_CONTEXT if \c ctx is invalid,
1495 * or zero if the request failed due to internal problems (i.e.,
1496 * unable to allocate temporary memory, etc.)
1499 * This function dynamically determines whether to use the EXT_import_context
1500 * version of the protocol or the GLX 1.3 version of the protocol.
1502 static int __glXQueryContextInfo(Display
*dpy
, GLXContext ctx
)
1504 __GLXdisplayPrivate
*priv
= __glXInitialize(dpy
);
1505 xGLXQueryContextReply reply
;
1511 return GLX_BAD_CONTEXT
;
1513 opcode
= __glXSetupForCommand(dpy
);
1518 /* Send the glXQueryContextInfoEXT request */
1521 if ( (priv
->majorVersion
> 1) || (priv
->minorVersion
>= 3) ) {
1522 xGLXQueryContextReq
*req
;
1524 GetReq(GLXQueryContext
, req
);
1526 req
->reqType
= opcode
;
1527 req
->glxCode
= X_GLXQueryContext
;
1528 req
->context
= (unsigned int)(ctx
->xid
);
1531 xGLXVendorPrivateReq
*vpreq
;
1532 xGLXQueryContextInfoEXTReq
*req
;
1534 GetReqExtra( GLXVendorPrivate
,
1535 sz_xGLXQueryContextInfoEXTReq
- sz_xGLXVendorPrivateReq
,
1537 req
= (xGLXQueryContextInfoEXTReq
*)vpreq
;
1538 req
->reqType
= opcode
;
1539 req
->glxCode
= X_GLXVendorPrivateWithReply
;
1540 req
->vendorCode
= X_GLXvop_QueryContextInfoEXT
;
1541 req
->context
= (unsigned int)(ctx
->xid
);
1544 _XReply(dpy
, (xReply
*) &reply
, 0, False
);
1546 numValues
= reply
.n
;
1549 else if (numValues
> __GLX_MAX_CONTEXT_PROPS
)
1553 int *propList
, *pProp
;
1557 nPropListBytes
= numValues
<< 3;
1558 propList
= (int *) Xmalloc(nPropListBytes
);
1559 if (NULL
== propList
) {
1562 _XRead(dpy
, (char *)propList
, nPropListBytes
);
1564 for (i
=0; i
< numValues
; i
++) {
1566 case GLX_SHARE_CONTEXT_EXT
:
1567 ctx
->share_xid
= *pProp
++;
1569 case GLX_VISUAL_ID_EXT
:
1570 ctx
->vid
= *pProp
++;
1573 ctx
->screen
= *pProp
++;
1575 case GLX_FBCONFIG_ID
:
1576 ctx
->fbconfigID
= *pProp
++;
1578 case GLX_RENDER_TYPE
:
1579 ctx
->renderType
= *pProp
++;
1586 Xfree((char *)propList
);
1596 GLX_PREFIX(glXQueryContext
)(Display
*dpy
, GLXContext ctx
,
1597 int attribute
, int *value
)
1601 /* get the information from the server if we don't have it already */
1602 if (!ctx
->isDirect
&& (ctx
->vid
== None
)) {
1603 retVal
= __glXQueryContextInfo(dpy
, ctx
);
1604 if (Success
!= retVal
) return retVal
;
1606 switch (attribute
) {
1607 case GLX_SHARE_CONTEXT_EXT
:
1608 *value
= (int)(ctx
->share_xid
);
1610 case GLX_VISUAL_ID_EXT
:
1611 *value
= (int)(ctx
->vid
);
1614 *value
= (int)(ctx
->screen
);
1616 case GLX_FBCONFIG_ID
:
1617 *value
= (int)(ctx
->fbconfigID
);
1619 case GLX_RENDER_TYPE
:
1620 *value
= (int)(ctx
->renderType
);
1623 return GLX_BAD_ATTRIBUTE
;
1628 PUBLIC
GLX_ALIAS( int, glXQueryContextInfoEXT
,
1629 (Display
*dpy
, GLXContext ctx
, int attribute
, int *value
),
1630 (dpy
, ctx
, attribute
, value
),
1633 PUBLIC GLXContextID
glXGetContextIDEXT(const GLXContext ctx
)
1638 PUBLIC GLXContext
GLX_PREFIX(glXImportContextEXT
)(Display
*dpy
,
1639 GLXContextID contextID
)
1643 if (contextID
== None
) {
1646 if (__glXIsDirect(dpy
, contextID
)) {
1650 ctx
= CreateContext(dpy
, NULL
, NULL
, NULL
, False
, contextID
, False
, 0);
1652 if (Success
!= __glXQueryContextInfo(dpy
, ctx
)) {
1659 PUBLIC
void GLX_PREFIX(glXFreeContextEXT
)(Display
*dpy
, GLXContext ctx
)
1661 DestroyContext(dpy
, ctx
);
1667 * GLX 1.3 functions - these are just stubs for now!
1670 PUBLIC GLXFBConfig
*GLX_PREFIX(glXChooseFBConfig
)(Display
*dpy
, int screen
,
1671 const int *attribList
,
1674 __GLcontextModes
** config_list
;
1678 config_list
= (__GLcontextModes
**)
1679 GLX_PREFIX(glXGetFBConfigs
)( dpy
, screen
, & list_size
);
1681 if ( (config_list
!= NULL
) && (list_size
> 0) && (attribList
!= NULL
) ) {
1682 list_size
= choose_visual( config_list
, list_size
, attribList
,
1684 if ( list_size
== 0 ) {
1685 XFree( config_list
);
1690 *nitems
= list_size
;
1691 return (GLXFBConfig
*) config_list
;
1695 PUBLIC GLXContext
GLX_PREFIX(glXCreateNewContext
)(Display
*dpy
,
1698 GLXContext shareList
,
1701 return CreateContext( dpy
, NULL
, (__GLcontextModes
*) config
, shareList
,
1702 allowDirect
, None
, True
, renderType
);
1706 PUBLIC GLXDrawable
GLX_PREFIX(glXGetCurrentReadDrawable
)(void)
1708 GLXContext gc
= __glXGetCurrentContext();
1709 return gc
->currentReadable
;
1713 PUBLIC GLXFBConfig
*GLX_PREFIX(glXGetFBConfigs
)(Display
*dpy
, int screen
,
1716 __GLXdisplayPrivate
*priv
= __glXInitialize(dpy
);
1717 __GLcontextModes
** config
= NULL
;
1720 if ( (priv
->screenConfigs
!= NULL
)
1721 && (screen
>= 0) && (screen
<= ScreenCount(dpy
))
1722 && (priv
->screenConfigs
[screen
].configs
!= NULL
)
1723 && (priv
->screenConfigs
[screen
].configs
->fbconfigID
!= GLX_DONT_CARE
) ) {
1724 unsigned num_configs
= 0;
1725 __GLcontextModes
* modes
;
1728 for ( modes
= priv
->screenConfigs
[screen
].configs
1730 ; modes
= modes
->next
) {
1731 if ( modes
->fbconfigID
!= GLX_DONT_CARE
) {
1736 config
= (__GLcontextModes
**) Xmalloc( sizeof(__GLcontextModes
*)
1738 if ( config
!= NULL
) {
1739 *nelements
= num_configs
;
1741 for ( modes
= priv
->screenConfigs
[screen
].configs
1743 ; modes
= modes
->next
) {
1749 return (GLXFBConfig
*) config
;
1753 PUBLIC
int GLX_PREFIX(glXGetFBConfigAttrib
)(Display
*dpy
, GLXFBConfig config
,
1754 int attribute
, int *value
)
1756 __GLcontextModes
* const modes
= ValidateGLXFBConfig( dpy
, config
);
1758 return (modes
!= NULL
)
1759 ? _gl_get_context_mode_data( modes
, attribute
, value
)
1764 PUBLIC XVisualInfo
*GLX_PREFIX(glXGetVisualFromFBConfig
)(Display
*dpy
,
1767 XVisualInfo visualTemplate
;
1768 __GLcontextModes
* fbconfig
= (__GLcontextModes
*) config
;
1772 ** Get a list of all visuals, return if list is empty
1774 visualTemplate
.visualid
= fbconfig
->visualID
;
1775 return XGetVisualInfo(dpy
,VisualIDMask
,&visualTemplate
,&count
);
1780 ** GLX_SGI_make_current_read
1783 PUBLIC
GLX_ALIAS(GLXDrawable
, glXGetCurrentReadDrawableSGI
, (void), (),
1784 glXGetCurrentReadDrawable
)
1788 ** GLX_SGI_swap_control
1790 PUBLIC
int GLX_PREFIX(glXSwapIntervalSGI
)(int interval
)
1792 xGLXVendorPrivateReq
*req
;
1793 GLXContext gc
= __glXGetCurrentContext();
1795 CARD32
* interval_ptr
;
1799 return GLX_BAD_CONTEXT
;
1802 if ( interval
<= 0 ) {
1803 return GLX_BAD_VALUE
;
1806 #ifdef GLX_DIRECT_RENDERING
1807 if ( gc
->isDirect
) {
1808 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs( gc
->currentDpy
,
1810 __DRIdrawable
* const pdraw
= GetDRIDrawable( gc
->currentDpy
,
1811 gc
->currentDrawable
,
1813 if ( __glXExtensionBitIsEnabled( psc
, SGI_swap_control_bit
)
1814 && (pdraw
!= NULL
) ) {
1815 pdraw
->swap_interval
= interval
;
1819 return GLX_BAD_CONTEXT
;
1823 dpy
= gc
->currentDpy
;
1824 opcode
= __glXSetupForCommand(dpy
);
1829 /* Send the glXSwapIntervalSGI request */
1831 GetReqExtra(GLXVendorPrivate
,sizeof(CARD32
),req
);
1832 req
->reqType
= opcode
;
1833 req
->glxCode
= X_GLXVendorPrivate
;
1834 req
->vendorCode
= X_GLXvop_SwapIntervalSGI
;
1835 req
->contextTag
= gc
->currentContextTag
;
1837 interval_ptr
= (CARD32
*) req
+ 1;
1838 *interval_ptr
= interval
;
1849 ** GLX_MESA_swap_control
1851 PUBLIC GLint
GLX_PREFIX(glXSwapIntervalMESA
)(unsigned interval
)
1853 #ifdef GLX_DIRECT_RENDERING
1854 GLXContext gc
= __glXGetCurrentContext();
1856 if ( interval
< 0 ) {
1857 return GLX_BAD_VALUE
;
1860 if ( (gc
!= NULL
) && gc
->isDirect
) {
1861 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs( gc
->currentDpy
,
1864 if ( (psc
!= NULL
) && (psc
->driScreen
.private != NULL
)
1865 && __glXExtensionBitIsEnabled( psc
, MESA_swap_control_bit
) ) {
1866 __DRIdrawable
* const pdraw
=
1867 (*psc
->driScreen
.getDrawable
)(gc
->currentDpy
,
1868 gc
->currentDrawable
,
1869 psc
->driScreen
.private);
1870 if ( pdraw
!= NULL
) {
1871 pdraw
->swap_interval
= interval
;
1880 return GLX_BAD_CONTEXT
;
1883 PUBLIC GLint
GLX_PREFIX(glXGetSwapIntervalMESA
)( void )
1885 #ifdef GLX_DIRECT_RENDERING
1886 GLXContext gc
= __glXGetCurrentContext();
1888 if ( (gc
!= NULL
) && gc
->isDirect
) {
1889 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs( gc
->currentDpy
,
1892 if ( (psc
!= NULL
) && (psc
->driScreen
.private != NULL
)
1893 && __glXExtensionBitIsEnabled( psc
, MESA_swap_control_bit
) ) {
1894 __DRIdrawable
* const pdraw
=
1895 (*psc
->driScreen
.getDrawable
)(gc
->currentDpy
,
1896 gc
->currentDrawable
,
1897 psc
->driScreen
.private);
1898 if ( pdraw
!= NULL
) {
1899 return pdraw
->swap_interval
;
1910 ** GLX_MESA_swap_frame_usage
1913 PUBLIC GLint
GLX_PREFIX(glXBeginFrameTrackingMESA
)(Display
*dpy
,
1914 GLXDrawable drawable
)
1916 int status
= GLX_BAD_CONTEXT
;
1917 #ifdef GLX_DIRECT_RENDERING
1919 __DRIdrawable
* const pdraw
= GetDRIDrawable(dpy
, drawable
, & screen
);
1920 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs(dpy
, screen
);
1922 if ( (pdraw
!= NULL
) && (pdraw
->frameTracking
!= NULL
)
1923 && __glXExtensionBitIsEnabled( psc
, MESA_swap_frame_usage_bit
) ) {
1924 status
= pdraw
->frameTracking( dpy
, pdraw
->private, GL_TRUE
);
1934 PUBLIC GLint
GLX_PREFIX(glXEndFrameTrackingMESA
)(Display
*dpy
,
1935 GLXDrawable drawable
)
1937 int status
= GLX_BAD_CONTEXT
;
1938 #ifdef GLX_DIRECT_RENDERING
1940 __DRIdrawable
* const pdraw
= GetDRIDrawable(dpy
, drawable
, & screen
);
1941 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs(dpy
, screen
);
1943 if ( (pdraw
!= NULL
) && (pdraw
->frameTracking
!= NULL
)
1944 && __glXExtensionBitIsEnabled( psc
, MESA_swap_frame_usage_bit
) ) {
1945 status
= pdraw
->frameTracking( dpy
, pdraw
->private, GL_FALSE
);
1955 PUBLIC GLint
GLX_PREFIX(glXGetFrameUsageMESA
)(Display
*dpy
,
1956 GLXDrawable drawable
,
1959 int status
= GLX_BAD_CONTEXT
;
1960 #ifdef GLX_DIRECT_RENDERING
1962 __DRIdrawable
* const pdraw
= GetDRIDrawable(dpy
, drawable
, & screen
);
1963 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs(dpy
, screen
);
1965 if ( (pdraw
!= NULL
) && (pdraw
->queryFrameTracking
!= NULL
)
1966 && __glXExtensionBitIsEnabled( psc
, MESA_swap_frame_usage_bit
) ) {
1967 int64_t sbc
, missedFrames
;
1968 float lastMissedUsage
;
1970 status
= pdraw
->queryFrameTracking( dpy
, pdraw
->private, &sbc
,
1971 &missedFrames
, &lastMissedUsage
,
1983 PUBLIC GLint
GLX_PREFIX(glXQueryFrameTrackingMESA
)(Display
*dpy
,
1984 GLXDrawable drawable
,
1986 int64_t *missedFrames
,
1987 GLfloat
*lastMissedUsage
)
1989 int status
= GLX_BAD_CONTEXT
;
1990 #ifdef GLX_DIRECT_RENDERING
1992 __DRIdrawable
* const pdraw
= GetDRIDrawable(dpy
, drawable
, & screen
);
1993 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs(dpy
, screen
);
1995 if ( (pdraw
!= NULL
) && (pdraw
->queryFrameTracking
!= NULL
)
1996 && __glXExtensionBitIsEnabled( psc
, MESA_swap_frame_usage_bit
) ) {
1999 status
= pdraw
->queryFrameTracking( dpy
, pdraw
->private, sbc
,
2000 missedFrames
, lastMissedUsage
,
2007 (void) missedFrames
;
2008 (void) lastMissedUsage
;
2015 ** GLX_SGI_video_sync
2017 PUBLIC
int GLX_PREFIX(glXGetVideoSyncSGI
)(unsigned int *count
)
2019 /* FIXME: Looking at the GLX_SGI_video_sync spec in the extension registry,
2020 * FIXME: there should be a GLX encoding for this call. I can find no
2021 * FIXME: documentation for the GLX encoding.
2023 #ifdef GLX_DIRECT_RENDERING
2024 GLXContext gc
= __glXGetCurrentContext();
2027 if ( (gc
!= NULL
) && gc
->isDirect
) {
2028 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs( gc
->currentDpy
,
2030 if ( __glXExtensionBitIsEnabled( psc
, SGI_video_sync_bit
)
2031 && psc
->driScreen
.private && psc
->driScreen
.getMSC
) {
2035 ret
= psc
->driScreen
.getMSC( psc
->driScreen
.private, & temp
);
2036 *count
= (unsigned) temp
;
2037 return (ret
== 0) ? 0 : GLX_BAD_CONTEXT
;
2043 return GLX_BAD_CONTEXT
;
2046 PUBLIC
int GLX_PREFIX(glXWaitVideoSyncSGI
)(int divisor
, int remainder
,
2047 unsigned int *count
)
2049 #ifdef GLX_DIRECT_RENDERING
2050 GLXContext gc
= __glXGetCurrentContext();
2052 if ( divisor
<= 0 || remainder
< 0 )
2053 return GLX_BAD_VALUE
;
2055 if ( (gc
!= NULL
) && gc
->isDirect
) {
2056 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs( gc
->currentDpy
,
2058 if ( __glXExtensionBitIsEnabled( psc
, SGI_video_sync_bit
)
2059 && psc
->driScreen
.private ) {
2060 __DRIdrawable
* const pdraw
=
2061 (*psc
->driScreen
.getDrawable
)(gc
->currentDpy
,
2062 gc
->currentDrawable
,
2063 psc
->driScreen
.private);
2064 if ( (pdraw
!= NULL
) && (pdraw
->waitForMSC
!= NULL
) ) {
2069 ret
= (*pdraw
->waitForMSC
)( gc
->currentDpy
, pdraw
->private,
2070 0, divisor
, remainder
,
2072 *count
= (unsigned) msc
;
2073 return (ret
== 0) ? 0 : GLX_BAD_CONTEXT
;
2080 return GLX_BAD_CONTEXT
;
2085 ** GLX_SGIS_video_source
2089 PUBLIC GLXVideoSourceSGIX
GLX_PREFIX(glXCreateGLXVideoSourceSGIX
)(Display
*dpy
,
2090 int screen
, VLServer server
, VLPath path
,
2091 int nodeClass
, VLNode drainNode
)
2102 PUBLIC
void GLX_PREFIX(glXDestroyGLXVideoSourceSGIX
)(Display
*dpy
,
2103 GLXVideoSourceSGIX src
)
2113 ** GLX_SGIX_fbconfig
2114 ** Many of these functions are aliased to GLX 1.3 entry points in the
2115 ** GLX_functions table.
2118 PUBLIC
GLX_ALIAS(int, glXGetFBConfigAttribSGIX
,
2119 (Display
*dpy
, GLXFBConfigSGIX config
, int attribute
, int *value
),
2120 (dpy
, config
, attribute
, value
),
2121 glXGetFBConfigAttrib
)
2123 PUBLIC
GLX_ALIAS(GLXFBConfigSGIX
*, glXChooseFBConfigSGIX
,
2124 (Display
*dpy
, int screen
, int *attrib_list
, int *nelements
),
2125 (dpy
, screen
, attrib_list
, nelements
),
2128 PUBLIC
GLX_ALIAS(XVisualInfo
*, glXGetVisualFromFBConfigSGIX
,
2129 (Display
* dpy
, GLXFBConfigSGIX config
),
2131 glXGetVisualFromFBConfig
)
2133 PUBLIC GLXPixmap
GLX_PREFIX(glXCreateGLXPixmapWithConfigSGIX
)(Display
*dpy
,
2134 GLXFBConfigSGIX config
, Pixmap pixmap
)
2136 xGLXVendorPrivateWithReplyReq
*vpreq
;
2137 xGLXCreateGLXPixmapWithConfigSGIXReq
*req
;
2138 GLXPixmap xid
= None
;
2140 const __GLcontextModes
* const fbconfig
= (__GLcontextModes
*) config
;
2141 __GLXscreenConfigs
* psc
;
2144 if ( (dpy
== NULL
) || (config
== NULL
) ) {
2148 psc
= GetGLXScreenConfigs( dpy
, fbconfig
->screen
);
2150 && __glXExtensionBitIsEnabled( psc
, SGIX_fbconfig_bit
) ) {
2151 opcode
= __glXSetupForCommand(dpy
);
2156 /* Send the glXCreateGLXPixmapWithConfigSGIX request */
2158 GetReqExtra(GLXVendorPrivateWithReply
,
2159 sz_xGLXCreateGLXPixmapWithConfigSGIXReq
-sz_xGLXVendorPrivateWithReplyReq
,vpreq
);
2160 req
= (xGLXCreateGLXPixmapWithConfigSGIXReq
*)vpreq
;
2161 req
->reqType
= opcode
;
2162 req
->glxCode
= X_GLXVendorPrivateWithReply
;
2163 req
->vendorCode
= X_GLXvop_CreateGLXPixmapWithConfigSGIX
;
2164 req
->screen
= fbconfig
->screen
;
2165 req
->fbconfig
= fbconfig
->fbconfigID
;
2166 req
->pixmap
= pixmap
;
2167 req
->glxpixmap
= xid
= XAllocID(dpy
);
2175 PUBLIC GLXContext
GLX_PREFIX(glXCreateContextWithConfigSGIX
)(Display
*dpy
,
2176 GLXFBConfigSGIX config
, int renderType
,
2177 GLXContext shareList
, Bool allowDirect
)
2179 GLXContext gc
= NULL
;
2180 const __GLcontextModes
* const fbconfig
= (__GLcontextModes
*) config
;
2181 __GLXscreenConfigs
* psc
;
2184 if ( (dpy
== NULL
) || (config
== NULL
) ) {
2188 psc
= GetGLXScreenConfigs( dpy
, fbconfig
->screen
);
2190 && __glXExtensionBitIsEnabled( psc
, SGIX_fbconfig_bit
) ) {
2191 gc
= CreateContext( dpy
, NULL
, (__GLcontextModes
*) config
, shareList
,
2192 allowDirect
, None
, False
, renderType
);
2199 PUBLIC GLXFBConfigSGIX
GLX_PREFIX(glXGetFBConfigFromVisualSGIX
)(Display
*dpy
,
2202 __GLXdisplayPrivate
*priv
;
2203 __GLXscreenConfigs
*psc
;
2205 if ( (GetGLXPrivScreenConfig( dpy
, vis
->screen
, & priv
, & psc
) != Success
)
2206 && __glXExtensionBitIsEnabled( psc
, SGIX_fbconfig_bit
)
2207 && (psc
->configs
->fbconfigID
!= GLX_DONT_CARE
) ) {
2208 return (GLXFBConfigSGIX
) _gl_context_modes_find_visual( psc
->configs
,
2219 PUBLIC
void GLX_PREFIX(glXCushionSGI
)(Display
*dpy
, Window win
, float cushion
)
2228 ** GLX_SGIX_video_resize
2230 PUBLIC
int GLX_PREFIX(glXBindChannelToWindowSGIX
)(Display
*dpy
, int screen
,
2231 int channel
, Window window
)
2240 PUBLIC
int GLX_PREFIX(glXChannelRectSGIX
)(Display
*dpy
, int screen
, int channel
,
2241 int x
, int y
, int w
, int h
)
2253 PUBLIC
int GLX_PREFIX(glXQueryChannelRectSGIX
)(Display
*dpy
, int screen
,
2254 int channel
, int *x
, int *y
,
2267 int GLX_PREFIX(glXQueryChannelDeltasSGIX
)(Display
*dpy
, int screen
, int channel
,
2268 int *dx
, int *dy
, int *dw
, int *dh
)
2280 PUBLIC
int GLX_PREFIX(glXChannelRectSyncSGIX
)(Display
*dpy
, int screen
,
2281 int channel
, GLenum synctype
)
2291 #if defined(_DM_BUFFER_H_)
2293 PUBLIC Bool
GLX_PREFIX(glXAssociateDMPbufferSGIX
)(Display
*dpy
,
2294 GLXPbufferSGIX pbuffer
,
2309 ** GLX_SGIX_swap_group
2311 PUBLIC
void GLX_PREFIX(glXJoinSwapGroupSGIX
)(Display
*dpy
, GLXDrawable drawable
,
2321 ** GLX_SGIX_swap_barrier
2323 PUBLIC
void GLX_PREFIX(glXBindSwapBarrierSGIX
)(Display
*dpy
,
2324 GLXDrawable drawable
,
2332 PUBLIC Bool
GLX_PREFIX(glXQueryMaxSwapBarriersSGIX
)(Display
*dpy
, int screen
,
2343 ** GLX_SUN_get_transparent_index
2345 PUBLIC Status
GLX_PREFIX(glXGetTransparentIndexSUN
)(Display
*dpy
,
2353 (void) pTransparent
;
2359 ** GLX_OML_sync_control
2361 PUBLIC Bool
GLX_PREFIX(glXGetSyncValuesOML
)(Display
*dpy
, GLXDrawable drawable
,
2362 int64_t *ust
, int64_t *msc
, int64_t *sbc
)
2364 #ifdef GLX_DIRECT_RENDERING
2365 __GLXdisplayPrivate
* const priv
= __glXInitialize(dpy
);
2367 if ( priv
!= NULL
) {
2369 __DRIdrawable
* const pdraw
= GetDRIDrawable( dpy
, drawable
, & i
);
2370 __GLXscreenConfigs
* const psc
= &priv
->screenConfigs
[i
];
2372 assert( (pdraw
== NULL
) || (i
!= -1) );
2373 return ( (pdraw
&& pdraw
->getSBC
&& psc
->driScreen
.getMSC
)
2374 && __glXExtensionBitIsEnabled( psc
, OML_sync_control_bit
)
2375 && ((*psc
->driScreen
.getMSC
)( psc
->driScreen
.private, msc
) == 0)
2376 && ((*pdraw
->getSBC
)( dpy
, psc
->driScreen
.private, sbc
) == 0)
2377 && (__glXGetUST( ust
) == 0) );
2391 * Determine the refresh rate of the specified drawable and display.
2393 * \param dpy Display whose refresh rate is to be determined.
2394 * \param drawable Drawable whose refresh rate is to be determined.
2395 * \param numerator Numerator of the refresh rate.
2396 * \param demoninator Denominator of the refresh rate.
2397 * \return If the refresh rate for the specified display and drawable could
2398 * be calculated, True is returned. Otherwise False is returned.
2400 * \note This function is implemented entirely client-side. A lot of other
2401 * functionality is required to export GLX_OML_sync_control, so on
2402 * XFree86 this function can be called for direct-rendering contexts
2403 * when GLX_OML_sync_control appears in the client extension string.
2406 PUBLIC Bool
GLX_PREFIX(glXGetMscRateOML
)(Display
* dpy
, GLXDrawable drawable
,
2407 int32_t * numerator
, int32_t * denominator
)
2409 #if defined( GLX_DIRECT_RENDERING ) && defined( XF86VIDMODE )
2410 __GLXdisplayPrivate
* const priv
= __glXInitialize(dpy
);
2413 if ( priv
!= NULL
) {
2414 XF86VidModeModeLine mode_line
;
2420 GetDRIDrawable( dpy
, drawable
, & screen_num
);
2421 if ( (screen_num
!= -1)
2422 && XF86VidModeQueryVersion( dpy
, & i
, & i
)
2423 && XF86VidModeGetModeLine( dpy
, screen_num
, & dot_clock
,
2425 unsigned n
= dot_clock
* 1000;
2426 unsigned d
= mode_line
.vtotal
* mode_line
.htotal
;
2428 # define V_INTERLACE 0x010
2429 # define V_DBLSCAN 0x020
2431 if ( (mode_line
.flags
& V_INTERLACE
) ) {
2434 else if ( (mode_line
.flags
& V_DBLSCAN
) ) {
2438 /* The OML_sync_control spec requires that if the refresh rate is a
2439 * whole number, that the returned numerator be equal to the refresh
2440 * rate and the denominator be 1.
2443 if ( (n
% d
) == 0 ) {
2448 static const unsigned f
[] = { 13, 11, 7, 5, 3, 2, 0 };
2451 /* This is a poor man's way to reduce a fraction. It's far from
2452 * perfect, but it will work well enough for this situation.
2455 for ( i
= 0 ; f
[i
] != 0 ; i
++ ) {
2456 while ( ((n
% f
[i
]) == 0) && ((d
% f
[i
]) == 0) ) {
2480 PUBLIC
int64_t GLX_PREFIX(glXSwapBuffersMscOML
)(Display
*dpy
,
2481 GLXDrawable drawable
,
2486 #ifdef GLX_DIRECT_RENDERING
2488 __DRIdrawable
*pdraw
= GetDRIDrawable( dpy
, drawable
, & screen
);
2489 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs( dpy
, screen
);
2491 /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE
2492 * error", but it also says "It [glXSwapBuffersMscOML] will return a value
2493 * of -1 if the function failed because of errors detected in the input
2496 if ( divisor
< 0 || remainder
< 0 || target_msc
< 0 )
2498 if ( divisor
> 0 && remainder
>= divisor
)
2501 if ( (pdraw
!= NULL
) && (pdraw
->swapBuffersMSC
!= NULL
)
2502 && __glXExtensionBitIsEnabled( psc
, OML_sync_control_bit
) ) {
2503 return (*pdraw
->swapBuffersMSC
)(dpy
, pdraw
->private, target_msc
,
2504 divisor
, remainder
);
2517 PUBLIC Bool
GLX_PREFIX(glXWaitForMscOML
)(Display
* dpy
, GLXDrawable drawable
,
2518 int64_t target_msc
, int64_t divisor
,
2519 int64_t remainder
, int64_t *ust
,
2520 int64_t *msc
, int64_t *sbc
)
2522 #ifdef GLX_DIRECT_RENDERING
2524 __DRIdrawable
*pdraw
= GetDRIDrawable( dpy
, drawable
, & screen
);
2525 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs( dpy
, screen
);
2528 /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE
2529 * error", but the return type in the spec is Bool.
2531 if ( divisor
< 0 || remainder
< 0 || target_msc
< 0 )
2533 if ( divisor
> 0 && remainder
>= divisor
)
2536 if ( (pdraw
!= NULL
) && (pdraw
->waitForMSC
!= NULL
)
2537 && __glXExtensionBitIsEnabled( psc
, OML_sync_control_bit
) ) {
2538 ret
= (*pdraw
->waitForMSC
)( dpy
, pdraw
->private, target_msc
,
2539 divisor
, remainder
, msc
, sbc
);
2541 /* __glXGetUST returns zero on success and non-zero on failure.
2542 * This function returns True on success and False on failure.
2544 return ( (ret
== 0) && (__glXGetUST( ust
) == 0) );
2560 PUBLIC Bool
GLX_PREFIX(glXWaitForSbcOML
)(Display
* dpy
, GLXDrawable drawable
,
2561 int64_t target_sbc
, int64_t *ust
,
2562 int64_t *msc
, int64_t *sbc
)
2564 #ifdef GLX_DIRECT_RENDERING
2566 __DRIdrawable
*pdraw
= GetDRIDrawable( dpy
, drawable
, & screen
);
2567 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs( dpy
, screen
);
2570 /* The OML_sync_control spec says this should "generate a GLX_BAD_VALUE
2571 * error", but the return type in the spec is Bool.
2573 if ( target_sbc
< 0 )
2576 if ( (pdraw
!= NULL
) && (pdraw
->waitForSBC
!= NULL
)
2577 && __glXExtensionBitIsEnabled( psc
, OML_sync_control_bit
)) {
2578 ret
= (*pdraw
->waitForSBC
)( dpy
, pdraw
->private, target_sbc
, msc
, sbc
);
2580 /* __glXGetUST returns zero on success and non-zero on failure.
2581 * This function returns True on success and False on failure.
2583 return( (ret
== 0) && (__glXGetUST( ust
) == 0) );
2598 * GLX_MESA_allocate_memory
2602 PUBLIC
void *GLX_PREFIX(glXAllocateMemoryMESA
)(Display
*dpy
, int scrn
,
2603 size_t size
, float readFreq
,
2604 float writeFreq
, float priority
)
2606 #ifdef GLX_DIRECT_RENDERING
2607 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs( dpy
, scrn
);
2609 if ( __glXExtensionBitIsEnabled( psc
, MESA_allocate_memory_bit
) ) {
2610 if (psc
&& psc
->driScreen
.private && psc
->driScreen
.allocateMemory
) {
2611 return (*psc
->driScreen
.allocateMemory
)( dpy
, scrn
, size
,
2612 readFreq
, writeFreq
,
2623 #endif /* GLX_DIRECT_RENDERING */
2629 PUBLIC
void GLX_PREFIX(glXFreeMemoryMESA
)(Display
*dpy
, int scrn
, void *pointer
)
2631 #ifdef GLX_DIRECT_RENDERING
2632 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs( dpy
, scrn
);
2634 if ( __glXExtensionBitIsEnabled( psc
, MESA_allocate_memory_bit
) ) {
2635 if (psc
&& psc
->driScreen
.private && psc
->driScreen
.freeMemory
) {
2636 (*psc
->driScreen
.freeMemory
)( dpy
, scrn
, pointer
);
2643 #endif /* GLX_DIRECT_RENDERING */
2647 PUBLIC GLuint
GLX_PREFIX(glXGetMemoryOffsetMESA
)( Display
*dpy
, int scrn
,
2648 const void *pointer
)
2650 #ifdef GLX_DIRECT_RENDERING
2651 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs( dpy
, scrn
);
2653 if ( __glXExtensionBitIsEnabled( psc
, MESA_allocate_memory_bit
) ) {
2654 if (psc
&& psc
->driScreen
.private && psc
->driScreen
.memoryOffset
) {
2655 return (*psc
->driScreen
.memoryOffset
)( dpy
, scrn
, pointer
);
2662 #endif /* GLX_DIRECT_RENDERING */
2670 * Mesa extension stubs. These will help reduce portability problems.
2675 * Release all buffers associated with the specified GLX drawable.
2678 * This function was intended for stand-alone Mesa. The issue there is that
2679 * the library doesn't get any notification when a window is closed. In
2680 * DRI there is a similar but slightly different issue. When GLX 1.3 is
2681 * supported, there are 3 different functions to destroy a drawable. It
2682 * should be possible to create GLX protocol (or have it determine which
2683 * protocol to use based on the type of the drawable) to have one function
2684 * do the work of 3. For the direct-rendering case, this function could
2685 * just call the driver's \c __DRIdrawableRec::destroyDrawable function.
2686 * This would reduce the frequency with which \c __driGarbageCollectDrawables
2687 * would need to be used. This really should be done as part of the new DRI
2690 * \sa http://oss.sgi.com/projects/ogl-sample/registry/MESA/release_buffers.txt
2691 * __driGarbageCollectDrawables
2692 * glXDestroyGLXPixmap
2693 * glXDestroyPbuffer glXDestroyPixmap glXDestroyWindow
2694 * glXDestroyGLXPbufferSGIX glXDestroyGLXVideoSourceSGIX
2696 PUBLIC Bool
GLX_PREFIX(glXReleaseBuffersMESA
)( Display
*dpy
, GLXDrawable d
)
2704 PUBLIC GLXPixmap
GLX_PREFIX(glXCreateGLXPixmapMESA
)( Display
*dpy
,
2705 XVisualInfo
*visual
,
2717 PUBLIC
void GLX_PREFIX(glXCopySubBufferMESA
)(Display
*dpy
, GLXDrawable drawable
,
2719 int width
, int height
)
2730 PUBLIC Bool
GLX_PREFIX(glXSet3DfxModeMESA
)( int mode
)
2740 * \c strdup is actually not a standard ANSI C or POSIX routine.
2741 * Irix will not define it if ANSI mode is in effect.
2746 __glXstrdup(const char *str
)
2749 copy
= (char *) Xmalloc(strlen(str
) + 1);
2757 ** glXGetProcAddress support
2760 struct name_address_pair
{
2765 #define GLX_FUNCTION(f) { # f, (GLvoid *) f }
2766 #define GLX_FUNCTION2(n,f) { # n, (GLvoid *) f }
2768 static const struct name_address_pair GLX_functions
[] = {
2769 /*** GLX_VERSION_1_0 ***/
2770 GLX_FUNCTION( glXChooseVisual
),
2771 GLX_FUNCTION( glXCopyContext
),
2772 GLX_FUNCTION( glXCreateContext
),
2773 GLX_FUNCTION( glXCreateGLXPixmap
),
2774 GLX_FUNCTION( glXDestroyContext
),
2775 GLX_FUNCTION( glXDestroyGLXPixmap
),
2776 GLX_FUNCTION( glXGetConfig
),
2777 GLX_FUNCTION( glXGetCurrentContext
),
2778 GLX_FUNCTION( glXGetCurrentDrawable
),
2779 GLX_FUNCTION( glXIsDirect
),
2780 GLX_FUNCTION( glXMakeCurrent
),
2781 GLX_FUNCTION( glXQueryExtension
),
2782 GLX_FUNCTION( glXQueryVersion
),
2783 GLX_FUNCTION( glXSwapBuffers
),
2784 GLX_FUNCTION( glXUseXFont
),
2785 GLX_FUNCTION( glXWaitGL
),
2786 GLX_FUNCTION( glXWaitX
),
2788 /*** GLX_VERSION_1_1 ***/
2789 GLX_FUNCTION( glXGetClientString
),
2790 GLX_FUNCTION( glXQueryExtensionsString
),
2791 GLX_FUNCTION( glXQueryServerString
),
2793 /*** GLX_VERSION_1_2 ***/
2794 GLX_FUNCTION( glXGetCurrentDisplay
),
2796 /*** GLX_VERSION_1_3 ***/
2797 GLX_FUNCTION( glXChooseFBConfig
),
2798 GLX_FUNCTION( glXCreateNewContext
),
2799 GLX_FUNCTION( glXCreatePbuffer
),
2800 GLX_FUNCTION( glXCreatePixmap
),
2801 GLX_FUNCTION( glXCreateWindow
),
2802 GLX_FUNCTION( glXDestroyPbuffer
),
2803 GLX_FUNCTION( glXDestroyPixmap
),
2804 GLX_FUNCTION( glXDestroyWindow
),
2805 GLX_FUNCTION( glXGetCurrentReadDrawable
),
2806 GLX_FUNCTION( glXGetFBConfigAttrib
),
2807 GLX_FUNCTION( glXGetFBConfigs
),
2808 GLX_FUNCTION( glXGetSelectedEvent
),
2809 GLX_FUNCTION( glXGetVisualFromFBConfig
),
2810 GLX_FUNCTION( glXMakeContextCurrent
),
2811 GLX_FUNCTION( glXQueryContext
),
2812 GLX_FUNCTION( glXQueryDrawable
),
2813 GLX_FUNCTION( glXSelectEvent
),
2815 /*** GLX_SGI_swap_control ***/
2816 GLX_FUNCTION( glXSwapIntervalSGI
),
2818 /*** GLX_SGI_video_sync ***/
2819 GLX_FUNCTION( glXGetVideoSyncSGI
),
2820 GLX_FUNCTION( glXWaitVideoSyncSGI
),
2822 /*** GLX_SGI_make_current_read ***/
2823 GLX_FUNCTION2( glXMakeCurrentReadSGI
, glXMakeContextCurrent
),
2824 GLX_FUNCTION2( glXGetCurrentReadDrawableSGI
, glXGetCurrentReadDrawable
),
2826 /*** GLX_SGIX_video_source ***/
2828 GLX_FUNCTION( glXCreateGLXVideoSourceSGIX
),
2829 GLX_FUNCTION( glXDestroyGLXVideoSourceSGIX
),
2832 /*** GLX_EXT_import_context ***/
2833 GLX_FUNCTION( glXFreeContextEXT
),
2834 GLX_FUNCTION( glXGetContextIDEXT
),
2835 GLX_FUNCTION2( glXGetCurrentDisplayEXT
, glXGetCurrentDisplay
),
2836 GLX_FUNCTION( glXImportContextEXT
),
2837 GLX_FUNCTION2( glXQueryContextInfoEXT
, glXQueryContext
),
2839 /*** GLX_SGIX_fbconfig ***/
2840 GLX_FUNCTION2( glXGetFBConfigAttribSGIX
, glXGetFBConfigAttrib
),
2841 GLX_FUNCTION2( glXChooseFBConfigSGIX
, glXChooseFBConfig
),
2842 GLX_FUNCTION( glXCreateGLXPixmapWithConfigSGIX
),
2843 GLX_FUNCTION( glXCreateContextWithConfigSGIX
),
2844 GLX_FUNCTION2( glXGetVisualFromFBConfigSGIX
, glXGetVisualFromFBConfig
),
2845 GLX_FUNCTION( glXGetFBConfigFromVisualSGIX
),
2847 /*** GLX_SGIX_pbuffer ***/
2848 GLX_FUNCTION( glXCreateGLXPbufferSGIX
),
2849 GLX_FUNCTION( glXDestroyGLXPbufferSGIX
),
2850 GLX_FUNCTION( glXQueryGLXPbufferSGIX
),
2851 GLX_FUNCTION( glXSelectEventSGIX
),
2852 GLX_FUNCTION( glXGetSelectedEventSGIX
),
2854 /*** GLX_SGI_cushion ***/
2855 GLX_FUNCTION( glXCushionSGI
),
2857 /*** GLX_SGIX_video_resize ***/
2858 GLX_FUNCTION( glXBindChannelToWindowSGIX
),
2859 GLX_FUNCTION( glXChannelRectSGIX
),
2860 GLX_FUNCTION( glXQueryChannelRectSGIX
),
2861 GLX_FUNCTION( glXQueryChannelDeltasSGIX
),
2862 GLX_FUNCTION( glXChannelRectSyncSGIX
),
2864 /*** GLX_SGIX_dmbuffer **/
2865 #if defined(_DM_BUFFER_H_)
2866 GLX_FUNCTION( glXAssociateDMPbufferSGIX
),
2869 /*** GLX_SGIX_swap_group ***/
2870 GLX_FUNCTION( glXJoinSwapGroupSGIX
),
2872 /*** GLX_SGIX_swap_barrier ***/
2873 GLX_FUNCTION( glXBindSwapBarrierSGIX
),
2874 GLX_FUNCTION( glXQueryMaxSwapBarriersSGIX
),
2876 /*** GLX_SUN_get_transparent_index ***/
2877 GLX_FUNCTION( glXGetTransparentIndexSUN
),
2879 /*** GLX_MESA_allocate_memory ***/
2880 GLX_FUNCTION( glXAllocateMemoryMESA
),
2881 GLX_FUNCTION( glXFreeMemoryMESA
),
2882 GLX_FUNCTION( glXGetMemoryOffsetMESA
),
2884 /*** GLX_MESA_copy_sub_buffer ***/
2885 GLX_FUNCTION( glXCopySubBufferMESA
),
2887 /*** GLX_MESA_pixmap_colormap ***/
2888 GLX_FUNCTION( glXCreateGLXPixmapMESA
),
2890 /*** GLX_MESA_release_buffers ***/
2891 GLX_FUNCTION( glXReleaseBuffersMESA
),
2893 /*** GLX_MESA_set_3dfx_mode ***/
2894 GLX_FUNCTION( glXSet3DfxModeMESA
),
2896 /*** GLX_MESA_swap_control ***/
2897 GLX_FUNCTION( glXSwapIntervalMESA
),
2898 GLX_FUNCTION( glXGetSwapIntervalMESA
),
2900 /*** GLX_MESA_swap_frame_usage ***/
2901 GLX_FUNCTION( glXBeginFrameTrackingMESA
),
2902 GLX_FUNCTION( glXEndFrameTrackingMESA
),
2903 GLX_FUNCTION( glXGetFrameUsageMESA
),
2904 GLX_FUNCTION( glXQueryFrameTrackingMESA
),
2906 /*** GLX_ARB_get_proc_address ***/
2907 GLX_FUNCTION( glXGetProcAddressARB
),
2910 GLX_FUNCTION2( glXGetProcAddress
, glXGetProcAddressARB
),
2912 /*** GLX_OML_sync_control ***/
2913 GLX_FUNCTION( glXWaitForSbcOML
),
2914 GLX_FUNCTION( glXWaitForMscOML
),
2915 GLX_FUNCTION( glXSwapBuffersMscOML
),
2916 GLX_FUNCTION( glXGetMscRateOML
),
2917 GLX_FUNCTION( glXGetSyncValuesOML
),
2919 #ifdef GLX_DIRECT_RENDERING
2921 *** Internal functions useful to DRI drivers
2922 *** With this, the DRI drivers shouldn't need dlopen()/dlsym() to
2923 *** access internal libGL functions which may or may not exist.
2925 GLX_FUNCTION( __glXInitialize
),
2926 GLX_FUNCTION( __glXFindDRIScreen
),
2927 GLX_FUNCTION( __glXGetInternalVersion
),
2928 GLX_FUNCTION( __glXWindowExists
),
2929 GLX_FUNCTION2( __glXCreateContextWithConfig
, XF86DRICreateContextWithConfig
),
2930 GLX_FUNCTION2( __glXGetDrawableInfo
, XF86DRIGetDrawableInfo
),
2932 /*** DRI configuration ***/
2933 GLX_FUNCTION( glXGetScreenDriver
),
2934 GLX_FUNCTION( glXGetDriverConfig
),
2936 GLX_FUNCTION( __glXScrEnableExtension
),
2938 GLX_FUNCTION( __glXGetUST
),
2940 GLX_FUNCTION2( __glXCreateContextModes
, _gl_context_modes_create
),
2941 GLX_FUNCTION2( __glXDestroyContextModes
, _gl_context_modes_destroy
),
2944 { NULL
, NULL
} /* end of list */
2948 static const GLvoid
*
2949 get_glx_proc_address(const char *funcName
)
2953 /* try static functions */
2954 for (i
= 0; GLX_functions
[i
].Name
; i
++) {
2955 if (strcmp(GLX_functions
[i
].Name
, funcName
) == 0)
2956 return GLX_functions
[i
].Address
;
2963 #ifndef GLX_BUILT_IN_XMESA
2965 * Get the address of a named GL function. This is the pre-GLX 1.4 name for
2966 * \c glXGetProcAddress.
2968 * \param procName Name of a GL or GLX function.
2969 * \returns A pointer to the named function
2971 * \sa glXGetProcAddress
2973 PUBLIC
void (*glXGetProcAddressARB(const GLubyte
*procName
))( void )
2975 typedef void (*gl_function
)( void );
2979 /* Search the table of GLX and internal functions first. If that
2980 * fails and the supplied name could be a valid core GL name, try
2981 * searching the core GL function table. This check is done to prevent
2982 * DRI based drivers from searching the core GL function table for
2983 * internal API functions.
2986 f
= (gl_function
) get_glx_proc_address((const char *) procName
);
2987 if ( (f
== NULL
) && (procName
[0] == 'g') && (procName
[1] == 'l')
2988 && (procName
[2] != 'X') ) {
2989 f
= (gl_function
) _glapi_get_proc_address((const char *) procName
);
2996 * Get the address of a named GL function. This is the GLX 1.4 name for
2997 * \c glXGetProcAddressARB.
2999 * \param procName Name of a GL or GLX function.
3000 * \returns A pointer to the named function
3002 * \sa glXGetProcAddressARB
3004 PUBLIC
void (*glXGetProcAddress(const GLubyte
*procName
))( void )
3005 #if defined(__GNUC__) && !defined(GLX_ALIAS_UNSUPPORTED)
3006 __attribute__ ((alias ("glXGetProcAddressARB")));
3009 return glXGetProcAddressARB(procName
);
3011 #endif /* __GNUC__ */
3012 #endif /* GLX_BUILT_IN_XMESA */
3015 #ifdef GLX_DIRECT_RENDERING
3017 * Retrieves the verion of the internal libGL API in YYYYMMDD format. This
3018 * might be used by the DRI drivers to determine how new libGL is at runtime.
3019 * Drivers should not call this function directly. They should instead use
3020 * \c glXGetProcAddress to obtain a pointer to the function.
3022 * \returns An 8-digit decimal number representing the internal libGL API in
3025 * \sa glXGetProcAddress, PFNGLXGETINTERNALVERSIONPROC
3027 * \since Internal API version 20021121.
3029 int __glXGetInternalVersion(void)
3032 * 20021121 - Initial version
3033 * 20021128 - Added __glXWindowExists() function
3034 * 20021207 - Added support for dynamic GLX extensions,
3035 * GLX_SGI_swap_control, GLX_SGI_video_sync,
3036 * GLX_OML_sync_control, and GLX_MESA_swap_control.
3037 * Never officially released. Do NOT test against
3038 * this version. Use 20030317 instead.
3039 * 20030317 - Added support GLX_SGIX_fbconfig,
3040 * GLX_MESA_swap_frame_usage, GLX_OML_swap_method,
3041 * GLX_{ARB,SGIS}_multisample, and
3042 * GLX_SGIX_visual_select_group.
3043 * 20030606 - Added support for GLX_SGI_make_current_read.
3044 * 20030813 - Made support for dynamic extensions multi-head aware.
3045 * 20030818 - Added support for GLX_MESA_allocate_memory in place of the
3046 * deprecated GLX_NV_vertex_array_range & GLX_MESA_agp_offset
3048 * 20031201 - Added support for the first round of DRI interface changes.
3049 * Do NOT test against this version! It has binary
3050 * compatibility bugs, use 20040317 instead.
3051 * 20040317 - Added the 'mode' field to __DRIcontextRec.
3052 * 20040415 - Added support for bindContext3 and unbindContext3.
3053 * 20040602 - Add __glXGetDrawableInfo. I though that was there
3061 static Bool windowExistsFlag
;
3063 static int windowExistsErrorHandler(Display
*dpy
, XErrorEvent
*xerr
)
3065 if (xerr
->error_code
== BadWindow
) {
3066 windowExistsFlag
= GL_FALSE
;
3072 * Determine if a window associated with a \c GLXDrawable exists on the
3073 * X-server. This function is not used internally by libGL. It is provided
3074 * as a utility function for DRI drivers.
3075 * Drivers should not call this function directly. They should instead use
3076 * \c glXGetProcAddress to obtain a pointer to the function.
3078 * \param dpy Display associated with the drawable to be queried.
3079 * \param draw \c GLXDrawable to test.
3081 * \returns \c GL_TRUE if a window exists that is associated with \c draw,
3082 * otherwise \c GL_FALSE is returned.
3084 * \warning This function is not currently thread-safe.
3086 * \sa glXGetProcAddress
3088 * \since Internal API version 20021128.
3090 static Bool
__glXWindowExists(Display
*dpy
, GLXDrawable draw
)
3092 XWindowAttributes xwa
;
3093 int (*oldXErrorHandler
)(Display
*, XErrorEvent
*);
3095 XSync(dpy
, GL_FALSE
);
3096 windowExistsFlag
= GL_TRUE
;
3097 oldXErrorHandler
= XSetErrorHandler(windowExistsErrorHandler
);
3098 XGetWindowAttributes(dpy
, draw
, &xwa
); /* dummy request */
3099 XSetErrorHandler(oldXErrorHandler
);
3100 return windowExistsFlag
;
3105 * Get the unadjusted system time (UST). Currently, the UST is measured in
3106 * microseconds since Epoc. The actual resolution of the UST may vary from
3107 * system to system, and the units may vary from release to release.
3108 * Drivers should not call this function directly. They should instead use
3109 * \c glXGetProcAddress to obtain a pointer to the function.
3111 * \param ust Location to store the 64-bit UST
3112 * \returns Zero on success or a negative errno value on failure.
3114 * \sa glXGetProcAddress, PFNGLXGETUSTPROC
3116 * \since Internal API version 20030317.
3118 int __glXGetUST( int64_t * ust
)
3122 if ( ust
== NULL
) {
3126 if ( gettimeofday( & tv
, NULL
) == 0 ) {
3127 ust
[0] = (tv
.tv_sec
* 1000000) + tv
.tv_usec
;
3133 #endif /* GLX_DIRECT_RENDERING */