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 static Bool
dummyBindContext2( Display
*dpy
, int scrn
,
76 GLXDrawable draw
, GLXDrawable read
, GLXContext gc
);
78 static Bool
dummyUnbindContext2( Display
*dpy
, int scrn
,
79 GLXDrawable draw
, GLXDrawable read
, GLXContext gc
);
81 /****************************************************************************/
84 * Used as glue when a driver does not support
85 * \c __DRIcontextRec::bindContext2.
87 * XXX .bindContext is only defined as a function pointer if
88 * !DRI_NEW_INTERFACE_ONLY.
90 * \sa DriverCreateContextWrapper, __DRIcontextRec::bindContext2
92 static Bool
dummyBindContext2( Display
*dpy
, int scrn
,
93 GLXDrawable draw
, GLXDrawable read
,
96 assert( draw
== read
);
97 return (*gc
->driContext
.bindContext
)( dpy
, scrn
, draw
, gc
);
101 * Used as glue when a driver does not support
102 * \c __DRIcontextRec::unbindContext2.
104 * XXX .unbindContext is only defined as a function pointer if
105 * !DRI_NEW_INTERFACE_ONLY.
107 * \sa DriverCreateContextWrapper, __DRIcontextRec::unbindContext2
109 static Bool
dummyUnbindContext2( Display
*dpy
, int scrn
,
110 GLXDrawable draw
, GLXDrawable read
,
113 assert( draw
== read
);
114 return (*gc
->driContext
.unbindContext
)( dpy
, scrn
, draw
, gc
, GL_FALSE
);
118 /****************************************************************************/
120 * Wrap the call to the driver's \c createContext function.
122 * The \c createContext function is wrapped because not all drivers support
123 * the "new" \c unbindContext2 and \c bindContext2 interfaces. libGL should
124 * not have to check to see which functions the driver supports. Instead,
125 * if either function is not supported it is wrapped. The wrappers test to
126 * make sure that both drawables are the same and pass control to the old
129 * \sa dummyBindContext2, dummyUnbindContext2,
130 * __DRIcontextRec::bindContext2, __DRIcontextRec::unbindContext2
133 static void * DriverCreateContextWrapper( const __GLXscreenConfigs
*psc
,
134 Display
*dpy
, XVisualInfo
*vis
,
137 const __GLcontextModes
*modes
,
140 void * ctx_priv
= NULL
;
142 if ( psc
->driScreen
.createNewContext
!= NULL
) {
143 assert( modes
!= NULL
);
144 ctx_priv
= (*psc
->driScreen
.createNewContext
)(dpy
, modes
, render_type
,
147 /* If the driver supports the createNewContext interface, then
148 * it MUST also support either the bindContext2 / unbindContext2
149 * interface or the bindContext3 / unbindContext3 interface.
152 assert( (ctx_priv
== NULL
) || (ctx
->unbindContext2
!= NULL
)
153 || (ctx
->unbindContext3
!= NULL
) );
154 assert( (ctx_priv
== NULL
) || (ctx
->bindContext2
!= NULL
)
155 || (ctx
->bindContext3
!= NULL
) );
159 ctx_priv
= (*psc
->driScreen
.createContext
)(dpy
, vis
, shared
, ctx
);
161 if ( ctx_priv
!= NULL
) {
162 if ( ctx
->unbindContext2
== NULL
) {
163 ctx
->unbindContext2
= dummyUnbindContext2
;
166 if ( ctx
->bindContext2
== NULL
) {
167 ctx
->bindContext2
= dummyBindContext2
;
178 /****************************************************************************/
180 * Get the __DRIdrawable for the drawable associated with a GLXContext
182 * \param dpy The display associated with \c drawable.
183 * \param drawable GLXDrawable whose __DRIdrawable part is to be retrieved.
184 * \returns A pointer to the context's __DRIdrawable on success, or NULL if
185 * the drawable is not associated with a direct-rendering context.
188 #ifdef GLX_DIRECT_RENDERING
189 static __DRIdrawable
*
190 GetDRIDrawable( Display
*dpy
, GLXDrawable drawable
, int * const scrn_num
)
192 __GLXdisplayPrivate
* const priv
= __glXInitialize(dpy
);
194 if ( (priv
!= NULL
) && (priv
->driDisplay
.private != NULL
) ) {
195 const unsigned screen_count
= ScreenCount(dpy
);
198 for ( i
= 0 ; i
< screen_count
; i
++ ) {
199 __DRIscreen
* const psc
= &priv
->screenConfigs
[i
].driScreen
;
200 __DRIdrawable
* const pdraw
= (psc
->private != NULL
)
201 ? (*psc
->getDrawable
)(dpy
, drawable
, psc
->private) : NULL
;
203 if ( pdraw
!= NULL
) {
204 if ( scrn_num
!= NULL
) {
218 * Get the GLX per-screen data structure associated with a GLX context.
220 * \param dpy Display for which the GLX per-screen information is to be
222 * \param scrn Screen on \c dpy for which the GLX per-screen information is
224 * \returns A pointer to the GLX per-screen data if \c dpy and \c scrn
225 * specify a valid GLX screen, or NULL otherwise.
227 * \todo Should this function validate that \c scrn is within the screen
228 * number range for \c dpy?
231 static __GLXscreenConfigs
*
232 GetGLXScreenConfigs(Display
*dpy
, int scrn
)
234 __GLXdisplayPrivate
* const priv
= __glXInitialize(dpy
);
236 return (priv
->screenConfigs
!= NULL
) ? &priv
->screenConfigs
[scrn
] : NULL
;
241 GetGLXPrivScreenConfig( Display
*dpy
, int scrn
, __GLXdisplayPrivate
** ppriv
,
242 __GLXscreenConfigs
** ppsc
)
244 /* Initialize the extension, if needed . This has the added value
245 * of initializing/allocating the display private
249 return GLX_NO_EXTENSION
;
252 *ppriv
= __glXInitialize(dpy
);
253 if ( *ppriv
== NULL
) {
254 return GLX_NO_EXTENSION
;
257 /* Check screen number to see if its valid */
258 if ((scrn
< 0) || (scrn
>= ScreenCount(dpy
))) {
259 return GLX_BAD_SCREEN
;
262 /* Check to see if the GL is supported on this screen */
263 *ppsc
= &((*ppriv
)->screenConfigs
[scrn
]);
264 if ( (*ppsc
)->configs
== NULL
) {
265 /* No support for GL on this screen regardless of visual */
266 return GLX_BAD_VISUAL
;
274 * Determine if a \c GLXFBConfig supplied by the application is valid.
276 * \param dpy Application supplied \c Display pointer.
277 * \param config Application supplied \c GLXFBConfig.
279 * \returns If the \c GLXFBConfig is valid, the a pointer to the matching
280 * \c __GLcontextModes structure is returned. Otherwise, \c NULL
283 static __GLcontextModes
*
284 ValidateGLXFBConfig( Display
* dpy
, GLXFBConfig config
)
286 __GLXdisplayPrivate
* const priv
= __glXInitialize(dpy
);
287 const unsigned num_screens
= ScreenCount(dpy
);
289 const __GLcontextModes
* modes
;
292 if ( priv
!= NULL
) {
293 for ( i
= 0 ; i
< num_screens
; i
++ ) {
294 for ( modes
= priv
->screenConfigs
[i
].configs
296 ; modes
= modes
->next
) {
297 if ( modes
== (__GLcontextModes
*) config
) {
298 return (__GLcontextModes
*) config
;
309 * \todo It should be possible to move the allocate of \c client_state_private
310 * later in the function for direct-rendering contexts. Direct-rendering
311 * contexts don't need to track client state, so they don't need that memory
314 * \todo Eliminate \c __glXInitVertexArrayState. Replace it with a new
315 * function called \c __glXAllocateClientState that allocates the memory and
316 * does all the initialization (including the pixel pack / unpack).
319 GLXContext
AllocateGLXContext( Display
*dpy
)
324 __GLXattribute
*state
;
329 opcode
= __glXSetupForCommand(dpy
);
334 /* Allocate our context record */
335 gc
= (GLXContext
) Xmalloc(sizeof(struct __GLXcontextRec
));
340 memset(gc
, 0, sizeof(struct __GLXcontextRec
));
342 state
= Xmalloc(sizeof(struct __GLXattributeRec
));
348 gc
->client_state_private
= state
;
349 memset(gc
->client_state_private
, 0, sizeof(struct __GLXattributeRec
));
350 state
->NoDrawArraysProtocol
= (getenv("LIBGL_NO_DRAWARRAYS") != NULL
);
353 ** Create a temporary buffer to hold GLX rendering commands. The size
354 ** of the buffer is selected so that the maximum number of GLX rendering
355 ** commands can fit in a single X packet and still have room in the X
356 ** packet for the GLXRenderReq header.
359 bufSize
= (XMaxRequestSize(dpy
) * 4) - sz_xGLXRenderReq
;
360 gc
->buf
= (GLubyte
*) Xmalloc(bufSize
);
362 Xfree(gc
->client_state_private
);
366 gc
->bufSize
= bufSize
;
368 /* Fill in the new context */
369 gc
->renderMode
= GL_RENDER
;
371 state
->storePack
.alignment
= 4;
372 state
->storeUnpack
.alignment
= 4;
374 __glXInitVertexArrayState(gc
);
376 gc
->attributes
.stackPointer
= &gc
->attributes
.stack
[0];
379 ** PERFORMANCE NOTE: A mode dependent fill image can speed things up.
380 ** Other code uses the fastImageUnpack bit, but it is never set
383 gc
->fastImageUnpack
= GL_FALSE
;
384 gc
->fillImage
= __glFillImage
;
385 gc
->isDirect
= GL_FALSE
;
387 gc
->bufEnd
= gc
->buf
+ bufSize
;
390 ** Set limit register so that there will be one command per packet
394 gc
->limit
= gc
->buf
+ bufSize
- __GLX_BUFFER_LIMIT_SIZE
;
397 gc
->majorOpcode
= opcode
;
400 ** Constrain the maximum drawing command size allowed to be
401 ** transfered using the X_GLXRender protocol request. First
402 ** constrain by a software limit, then constrain by the protocl
405 if (bufSize
> __GLX_RENDER_CMD_SIZE_LIMIT
) {
406 bufSize
= __GLX_RENDER_CMD_SIZE_LIMIT
;
408 if (bufSize
> __GLX_MAX_RENDER_CMD_SIZE
) {
409 bufSize
= __GLX_MAX_RENDER_CMD_SIZE
;
411 gc
->maxSmallRenderCommandSize
= bufSize
;
417 * Create a new context. Exactly one of \c vis and \c fbconfig should be
420 * \param use_glx_1_3 For FBConfigs, should GLX 1.3 protocol or
421 * SGIX_fbconfig protocol be used?
422 * \param renderType For FBConfigs, what is the rendering type?
426 CreateContext(Display
*dpy
, XVisualInfo
*vis
,
427 const __GLcontextModes
* const fbconfig
,
428 GLXContext shareList
,
429 Bool allowDirect
, GLXContextID contextID
,
430 Bool use_glx_1_3
, int renderType
)
437 gc
= AllocateGLXContext(dpy
);
441 if (None
== contextID
) {
442 if ( (vis
== NULL
) && (fbconfig
== NULL
) )
445 #ifdef GLX_DIRECT_RENDERING
447 int screen
= (fbconfig
== NULL
) ? vis
->screen
: fbconfig
->screen
;
448 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs(dpy
, screen
);
449 const __GLcontextModes
* mode
;
451 /* The value of fbconfig cannot change because it is tested
452 * later in the function.
454 if ( fbconfig
== NULL
) {
455 /* FIXME: Is it possible for the __GLcontextModes structure
456 * FIXME: to not be found?
458 mode
= _gl_context_modes_find_visual( psc
->configs
,
460 assert( mode
!= NULL
);
461 assert( mode
->screen
== screen
);
467 if (psc
&& psc
->driScreen
.private) {
468 void * const shared
= (shareList
!= NULL
)
469 ? shareList
->driContext
.private : NULL
;
470 gc
->driContext
.private =
471 DriverCreateContextWrapper( psc
, dpy
, vis
, shared
,
472 &gc
->driContext
, mode
,
474 if (gc
->driContext
.private) {
475 gc
->isDirect
= GL_TRUE
;
476 gc
->screen
= mode
->screen
;
477 gc
->vid
= mode
->visualID
;
478 gc
->fbconfigID
= mode
->fbconfigID
;
479 gc
->driContext
.mode
= mode
;
486 if ( fbconfig
== NULL
) {
487 xGLXCreateContextReq
*req
;
489 /* Send the glXCreateContext request */
490 GetReq(GLXCreateContext
,req
);
491 req
->reqType
= gc
->majorOpcode
;
492 req
->glxCode
= X_GLXCreateContext
;
493 req
->context
= gc
->xid
= XAllocID(dpy
);
494 req
->visual
= vis
->visualid
;
495 req
->screen
= vis
->screen
;
496 req
->shareList
= shareList
? shareList
->xid
: None
;
497 req
->isDirect
= gc
->isDirect
;
499 else if ( use_glx_1_3
) {
500 xGLXCreateNewContextReq
*req
;
502 /* Send the glXCreateNewContext request */
503 GetReq(GLXCreateNewContext
,req
);
504 req
->reqType
= gc
->majorOpcode
;
505 req
->glxCode
= X_GLXCreateNewContext
;
506 req
->context
= gc
->xid
= XAllocID(dpy
);
507 req
->fbconfig
= fbconfig
->fbconfigID
;
508 req
->screen
= fbconfig
->screen
;
509 req
->renderType
= renderType
;
510 req
->shareList
= shareList
? shareList
->xid
: None
;
511 req
->isDirect
= gc
->isDirect
;
514 xGLXVendorPrivateWithReplyReq
*vpreq
;
515 xGLXCreateContextWithConfigSGIXReq
*req
;
517 /* Send the glXCreateNewContext request */
518 GetReqExtra(GLXVendorPrivateWithReply
,
519 sz_xGLXCreateContextWithConfigSGIXReq
-sz_xGLXVendorPrivateWithReplyReq
,vpreq
);
520 req
= (xGLXCreateContextWithConfigSGIXReq
*)vpreq
;
521 req
->reqType
= gc
->majorOpcode
;
522 req
->glxCode
= X_GLXVendorPrivateWithReply
;
523 req
->vendorCode
= X_GLXvop_CreateContextWithConfigSGIX
;
524 req
->context
= gc
->xid
= XAllocID(dpy
);
525 req
->fbconfig
= fbconfig
->fbconfigID
;
526 req
->screen
= fbconfig
->screen
;
527 req
->renderType
= renderType
;
528 req
->shareList
= shareList
? shareList
->xid
: None
;
529 req
->isDirect
= gc
->isDirect
;
534 gc
->imported
= GL_FALSE
;
538 gc
->imported
= GL_TRUE
;
544 PUBLIC GLXContext
GLX_PREFIX(glXCreateContext
)(Display
*dpy
, XVisualInfo
*vis
,
545 GLXContext shareList
,
548 return CreateContext(dpy
, vis
, NULL
, shareList
, allowDirect
, None
,
552 void __glXFreeContext(__GLXcontext
*gc
)
554 if (gc
->vendor
) XFree((char *) gc
->vendor
);
555 if (gc
->renderer
) XFree((char *) gc
->renderer
);
556 if (gc
->version
) XFree((char *) gc
->version
);
557 if (gc
->extensions
) XFree((char *) gc
->extensions
);
558 __glFreeAttributeState(gc
);
559 XFree((char *) gc
->buf
);
560 Xfree((char *) gc
->client_state_private
);
566 ** Destroy the named context
569 DestroyContext(Display
*dpy
, GLXContext gc
)
571 xGLXDestroyContextReq
*req
;
576 opcode
= __glXSetupForCommand(dpy
);
577 if (!opcode
|| !gc
) {
583 imported
= gc
->imported
;
586 #ifdef GLX_DIRECT_RENDERING
587 /* Destroy the direct rendering context */
589 if (gc
->driContext
.private) {
590 (*gc
->driContext
.destroyContext
)(dpy
, gc
->screen
,
591 gc
->driContext
.private);
592 gc
->driContext
.private = NULL
;
597 if (gc
->currentDpy
) {
598 /* Have to free later cuz it's in use now */
601 /* Destroy the handle if not current to anybody */
603 __glXFreeContext(gc
);
608 ** This dpy also created the server side part of the context.
609 ** Send the glXDestroyContext request.
612 GetReq(GLXDestroyContext
,req
);
613 req
->reqType
= opcode
;
614 req
->glxCode
= X_GLXDestroyContext
;
621 PUBLIC
void GLX_PREFIX(glXDestroyContext
)(Display
*dpy
, GLXContext gc
)
623 DestroyContext(dpy
, gc
);
627 ** Return the major and minor version #s for the GLX extension
629 PUBLIC Bool
GLX_PREFIX(glXQueryVersion
)(Display
*dpy
, int *major
, int *minor
)
631 __GLXdisplayPrivate
*priv
;
633 /* Init the extension. This fetches the major and minor version. */
634 priv
= __glXInitialize(dpy
);
635 if (!priv
) return GL_FALSE
;
637 if (major
) *major
= priv
->majorVersion
;
638 if (minor
) *minor
= priv
->minorVersion
;
643 ** Query the existance of the GLX extension
645 PUBLIC Bool
GLX_PREFIX(glXQueryExtension
)(Display
*dpy
, int *errorBase
,
648 int major_op
, erb
, evb
;
651 rv
= XQueryExtension(dpy
, GLX_EXTENSION_NAME
, &major_op
, &evb
, &erb
);
653 if (errorBase
) *errorBase
= erb
;
654 if (eventBase
) *eventBase
= evb
;
660 ** Put a barrier in the token stream that forces the GL to finish its
661 ** work before X can proceed.
663 PUBLIC
void GLX_PREFIX(glXWaitGL
)(void)
666 GLXContext gc
= __glXGetCurrentContext();
667 Display
*dpy
= gc
->currentDpy
;
671 /* Flush any pending commands out */
672 __glXFlushRenderBuffer(gc
, gc
->pc
);
674 #ifdef GLX_DIRECT_RENDERING
676 /* This bit of ugliness unwraps the glFinish function */
685 /* Send the glXWaitGL request */
687 GetReq(GLXWaitGL
,req
);
688 req
->reqType
= gc
->majorOpcode
;
689 req
->glxCode
= X_GLXWaitGL
;
690 req
->contextTag
= gc
->currentContextTag
;
696 ** Put a barrier in the token stream that forces X to finish its
697 ** work before GL can proceed.
699 PUBLIC
void GLX_PREFIX(glXWaitX
)(void)
702 GLXContext gc
= __glXGetCurrentContext();
703 Display
*dpy
= gc
->currentDpy
;
707 /* Flush any pending commands out */
708 __glXFlushRenderBuffer(gc
, gc
->pc
);
710 #ifdef GLX_DIRECT_RENDERING
718 ** Send the glXWaitX request.
721 GetReq(GLXWaitX
,req
);
722 req
->reqType
= gc
->majorOpcode
;
723 req
->glxCode
= X_GLXWaitX
;
724 req
->contextTag
= gc
->currentContextTag
;
729 PUBLIC
void GLX_PREFIX(glXUseXFont
)(Font font
, int first
, int count
,
732 xGLXUseXFontReq
*req
;
733 GLXContext gc
= __glXGetCurrentContext();
734 Display
*dpy
= gc
->currentDpy
;
738 /* Flush any pending commands out */
739 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
741 #ifdef GLX_DIRECT_RENDERING
743 DRI_glXUseXFont(font
, first
, count
, listBase
);
748 /* Send the glXUseFont request */
750 GetReq(GLXUseXFont
,req
);
751 req
->reqType
= gc
->majorOpcode
;
752 req
->glxCode
= X_GLXUseXFont
;
753 req
->contextTag
= gc
->currentContextTag
;
757 req
->listBase
= listBase
;
762 /************************************************************************/
765 ** Copy the source context to the destination context using the
768 PUBLIC
void GLX_PREFIX(glXCopyContext
)(Display
*dpy
, GLXContext source
,
769 GLXContext dest
, unsigned long mask
)
771 xGLXCopyContextReq
*req
;
772 GLXContext gc
= __glXGetCurrentContext();
776 opcode
= __glXSetupForCommand(dpy
);
781 #ifdef GLX_DIRECT_RENDERING
783 /* NOT_DONE: This does not work yet */
788 ** If the source is the current context, send its tag so that the context
789 ** can be flushed before the copy.
791 if (source
== gc
&& dpy
== gc
->currentDpy
) {
792 tag
= gc
->currentContextTag
;
797 /* Send the glXCopyContext request */
799 GetReq(GLXCopyContext
,req
);
800 req
->reqType
= opcode
;
801 req
->glxCode
= X_GLXCopyContext
;
802 req
->source
= source
? source
->xid
: None
;
803 req
->dest
= dest
? dest
->xid
: None
;
805 req
->contextTag
= tag
;
812 * Determine if a context uses direct rendering.
814 * \param dpy Display where the context was created.
815 * \param contextID ID of the context to be tested.
817 * \returns \c GL_TRUE if the context is direct rendering or not.
819 static Bool
__glXIsDirect(Display
*dpy
, GLXContextID contextID
)
821 xGLXIsDirectReq
*req
;
822 xGLXIsDirectReply reply
;
825 opcode
= __glXSetupForCommand(dpy
);
830 /* Send the glXIsDirect request */
832 GetReq(GLXIsDirect
,req
);
833 req
->reqType
= opcode
;
834 req
->glxCode
= X_GLXIsDirect
;
835 req
->context
= contextID
;
836 _XReply(dpy
, (xReply
*) &reply
, 0, False
);
840 return reply
.isDirect
;
843 PUBLIC Bool
GLX_PREFIX(glXIsDirect
)(Display
*dpy
, GLXContext gc
)
847 #ifdef GLX_DIRECT_RENDERING
848 } else if (gc
->isDirect
) {
852 return __glXIsDirect(dpy
, gc
->xid
);
855 PUBLIC GLXPixmap
GLX_PREFIX(glXCreateGLXPixmap
)(Display
*dpy
, XVisualInfo
*vis
,
858 xGLXCreateGLXPixmapReq
*req
;
862 opcode
= __glXSetupForCommand(dpy
);
867 /* Send the glXCreateGLXPixmap request */
869 GetReq(GLXCreateGLXPixmap
,req
);
870 req
->reqType
= opcode
;
871 req
->glxCode
= X_GLXCreateGLXPixmap
;
872 req
->screen
= vis
->screen
;
873 req
->visual
= vis
->visualid
;
874 req
->pixmap
= pixmap
;
875 req
->glxpixmap
= xid
= XAllocID(dpy
);
882 ** Destroy the named pixmap
884 PUBLIC
void GLX_PREFIX(glXDestroyGLXPixmap
)(Display
*dpy
, GLXPixmap glxpixmap
)
886 xGLXDestroyGLXPixmapReq
*req
;
889 opcode
= __glXSetupForCommand(dpy
);
894 /* Send the glXDestroyGLXPixmap request */
896 GetReq(GLXDestroyGLXPixmap
,req
);
897 req
->reqType
= opcode
;
898 req
->glxCode
= X_GLXDestroyGLXPixmap
;
899 req
->glxpixmap
= glxpixmap
;
904 PUBLIC
void GLX_PREFIX(glXSwapBuffers
)(Display
*dpy
, GLXDrawable drawable
)
906 xGLXSwapBuffersReq
*req
;
910 #ifdef GLX_DIRECT_RENDERING
911 __DRIdrawable
*pdraw
= GetDRIDrawable( dpy
, drawable
, NULL
);
913 if ( pdraw
!= NULL
) {
914 (*pdraw
->swapBuffers
)(dpy
, pdraw
->private);
919 opcode
= __glXSetupForCommand(dpy
);
925 ** The calling thread may or may not have a current context. If it
926 ** does, send the context tag so the server can do a flush.
928 gc
= __glXGetCurrentContext();
929 if ((gc
!= NULL
) && (dpy
== gc
->currentDpy
) &&
930 ((drawable
== gc
->currentDrawable
) || (drawable
== gc
->currentReadable
)) ) {
931 tag
= gc
->currentContextTag
;
936 /* Send the glXSwapBuffers request */
938 GetReq(GLXSwapBuffers
,req
);
939 req
->reqType
= opcode
;
940 req
->glxCode
= X_GLXSwapBuffers
;
941 req
->drawable
= drawable
;
942 req
->contextTag
= tag
;
950 ** Return configuration information for the given display, screen and
951 ** visual combination.
953 PUBLIC
int GLX_PREFIX(glXGetConfig
)(Display
*dpy
, XVisualInfo
*vis
,
954 int attribute
, int *value_return
)
956 __GLXdisplayPrivate
*priv
;
957 __GLXscreenConfigs
*psc
;
960 status
= GetGLXPrivScreenConfig( dpy
, vis
->screen
, & priv
, & psc
);
961 if ( status
== Success
) {
962 const __GLcontextModes
* const modes
= _gl_context_modes_find_visual(
963 psc
->configs
, vis
->visualid
);
965 /* Lookup attribute after first finding a match on the visual */
966 if ( modes
!= NULL
) {
967 return _gl_get_context_mode_data( modes
, attribute
, value_return
);
970 status
= GLX_BAD_VISUAL
;
974 ** If we can't find the config for this visual, this visual is not
975 ** supported by the OpenGL implementation on the server.
977 if ( (status
== GLX_BAD_VISUAL
) && (attribute
== GLX_USE_GL
) ) {
978 *value_return
= GL_FALSE
;
985 /************************************************************************/
988 init_fbconfig_for_chooser( __GLcontextModes
* config
,
989 GLboolean fbconfig_style_tags
)
991 memset( config
, 0, sizeof( __GLcontextModes
) );
992 config
->visualID
= (XID
) GLX_DONT_CARE
;
993 config
->visualType
= GLX_DONT_CARE
;
995 /* glXChooseFBConfig specifies different defaults for these two than
998 if ( fbconfig_style_tags
) {
999 config
->rgbMode
= GL_TRUE
;
1000 config
->doubleBufferMode
= GLX_DONT_CARE
;
1003 config
->visualRating
= GLX_DONT_CARE
;
1004 config
->transparentPixel
= GLX_NONE
;
1005 config
->transparentRed
= GLX_DONT_CARE
;
1006 config
->transparentGreen
= GLX_DONT_CARE
;
1007 config
->transparentBlue
= GLX_DONT_CARE
;
1008 config
->transparentAlpha
= GLX_DONT_CARE
;
1009 config
->transparentIndex
= GLX_DONT_CARE
;
1011 config
->drawableType
= GLX_WINDOW_BIT
;
1012 config
->renderType
= (config
->rgbMode
) ? GLX_RGBA_BIT
: GLX_COLOR_INDEX_BIT
;
1013 config
->xRenderable
= GLX_DONT_CARE
;
1014 config
->fbconfigID
= (GLXFBConfigID
)(GLX_DONT_CARE
);
1016 config
->swapMethod
= GLX_DONT_CARE
;
1019 #define MATCH_DONT_CARE( param ) \
1021 if ( (a-> param != GLX_DONT_CARE) \
1022 && (a-> param != b-> param) ) { \
1027 #define MATCH_MINIMUM( param ) \
1029 if ( (a-> param != GLX_DONT_CARE) \
1030 && (a-> param > b-> param) ) { \
1035 #define MATCH_EXACT( param ) \
1037 if ( a-> param != b-> param) { \
1043 * Determine if two GLXFBConfigs are compatible.
1045 * \param a Application specified config to test.
1046 * \param b Server specified config to test against \c a.
1049 fbconfigs_compatible( const __GLcontextModes
* const a
,
1050 const __GLcontextModes
* const b
)
1052 MATCH_DONT_CARE( doubleBufferMode
);
1053 MATCH_DONT_CARE( visualType
);
1054 MATCH_DONT_CARE( visualRating
);
1055 MATCH_DONT_CARE( xRenderable
);
1056 MATCH_DONT_CARE( fbconfigID
);
1057 MATCH_DONT_CARE( swapMethod
);
1059 MATCH_MINIMUM( rgbBits
);
1060 MATCH_MINIMUM( numAuxBuffers
);
1061 MATCH_MINIMUM( redBits
);
1062 MATCH_MINIMUM( greenBits
);
1063 MATCH_MINIMUM( blueBits
);
1064 MATCH_MINIMUM( alphaBits
);
1065 MATCH_MINIMUM( depthBits
);
1066 MATCH_MINIMUM( stencilBits
);
1067 MATCH_MINIMUM( accumRedBits
);
1068 MATCH_MINIMUM( accumGreenBits
);
1069 MATCH_MINIMUM( accumBlueBits
);
1070 MATCH_MINIMUM( accumAlphaBits
);
1071 MATCH_MINIMUM( sampleBuffers
);
1072 MATCH_MINIMUM( maxPbufferWidth
);
1073 MATCH_MINIMUM( maxPbufferHeight
);
1074 MATCH_MINIMUM( maxPbufferPixels
);
1075 MATCH_MINIMUM( samples
);
1077 MATCH_DONT_CARE( stereoMode
);
1078 MATCH_EXACT( level
);
1080 if ( ((a
->drawableType
& b
->drawableType
) == 0)
1081 || ((a
->renderType
& b
->renderType
) == 0) ) {
1086 /* There is a bug in a few of the XFree86 DDX drivers. They contain
1087 * visuals with a "transparent type" of 0 when they really mean GLX_NONE.
1088 * Technically speaking, it is a bug in the DDX driver, but there is
1089 * enough of an installed base to work around the problem here. In any
1090 * case, 0 is not a valid value of the transparent type, so we'll treat 0
1091 * from the app as GLX_DONT_CARE. We'll consider GLX_NONE from the app and
1092 * 0 from the server to be a match to maintain backward compatibility with
1093 * the (broken) drivers.
1096 if ( a
->transparentPixel
!= GLX_DONT_CARE
1097 && a
->transparentPixel
!= 0 ) {
1098 if ( a
->transparentPixel
== GLX_NONE
) {
1099 if ( b
->transparentPixel
!= GLX_NONE
&& b
->transparentPixel
!= 0 )
1102 MATCH_EXACT( transparentPixel
);
1105 switch ( a
->transparentPixel
) {
1106 case GLX_TRANSPARENT_RGB
:
1107 MATCH_DONT_CARE( transparentRed
);
1108 MATCH_DONT_CARE( transparentGreen
);
1109 MATCH_DONT_CARE( transparentBlue
);
1110 MATCH_DONT_CARE( transparentAlpha
);
1113 case GLX_TRANSPARENT_INDEX
:
1114 MATCH_DONT_CARE( transparentIndex
);
1126 /* There's some trickly language in the GLX spec about how this is supposed
1127 * to work. Basically, if a given component size is either not specified
1128 * or the requested size is zero, it is supposed to act like PERFER_SMALLER.
1129 * Well, that's really hard to do with the code as-is. This behavior is
1130 * closer to correct, but still not technically right.
1132 #define PREFER_LARGER_OR_ZERO(comp) \
1134 if ( ((*a)-> comp) != ((*b)-> comp) ) { \
1135 if ( ((*a)-> comp) == 0 ) { \
1138 else if ( ((*b)-> comp) == 0 ) { \
1142 return ((*b)-> comp) - ((*a)-> comp) ; \
1147 #define PREFER_LARGER(comp) \
1149 if ( ((*a)-> comp) != ((*b)-> comp) ) { \
1150 return ((*b)-> comp) - ((*a)-> comp) ; \
1154 #define PREFER_SMALLER(comp) \
1156 if ( ((*a)-> comp) != ((*b)-> comp) ) { \
1157 return ((*a)-> comp) - ((*b)-> comp) ; \
1162 * Compare two GLXFBConfigs. This function is intended to be used as the
1163 * compare function passed in to qsort.
1165 * \returns If \c a is a "better" config, according to the specification of
1166 * SGIX_fbconfig, a number less than zero is returned. If \c b is
1167 * better, then a number greater than zero is return. If both are
1168 * equal, zero is returned.
1169 * \sa qsort, glXChooseVisual, glXChooseFBConfig, glXChooseFBConfigSGIX
1172 fbconfig_compare( const __GLcontextModes
* const * const a
,
1173 const __GLcontextModes
* const * const b
)
1175 /* The order of these comparisons must NOT change. It is defined by
1176 * the GLX 1.3 spec and ARB_multisample.
1179 PREFER_SMALLER( visualSelectGroup
);
1181 /* The sort order for the visualRating is GLX_NONE, GLX_SLOW, and
1182 * GLX_NON_CONFORMANT_CONFIG. It just so happens that this is the
1183 * numerical sort order of the enums (0x8000, 0x8001, and 0x800D).
1185 PREFER_SMALLER( visualRating
);
1187 /* This isn't quite right. It is supposed to compare the sum of the
1188 * components the user specifically set minimums for.
1190 PREFER_LARGER_OR_ZERO( redBits
);
1191 PREFER_LARGER_OR_ZERO( greenBits
);
1192 PREFER_LARGER_OR_ZERO( blueBits
);
1193 PREFER_LARGER_OR_ZERO( alphaBits
);
1195 PREFER_SMALLER( rgbBits
);
1197 if ( ((*a
)->doubleBufferMode
!= (*b
)->doubleBufferMode
) ) {
1198 /* Prefer single-buffer.
1200 return ( !(*a
)->doubleBufferMode
) ? -1 : 1;
1203 PREFER_SMALLER( numAuxBuffers
);
1205 PREFER_LARGER_OR_ZERO( depthBits
);
1206 PREFER_SMALLER( stencilBits
);
1208 /* This isn't quite right. It is supposed to compare the sum of the
1209 * components the user specifically set minimums for.
1211 PREFER_LARGER_OR_ZERO( accumRedBits
);
1212 PREFER_LARGER_OR_ZERO( accumGreenBits
);
1213 PREFER_LARGER_OR_ZERO( accumBlueBits
);
1214 PREFER_LARGER_OR_ZERO( accumAlphaBits
);
1216 PREFER_SMALLER( visualType
);
1218 /* None of the multisample specs say where this comparison should happen,
1219 * so I put it near the end.
1221 PREFER_SMALLER( sampleBuffers
);
1222 PREFER_SMALLER( samples
);
1224 /* None of the pbuffer or fbconfig specs say that this comparison needs
1225 * to happen at all, but it seems like it should.
1227 PREFER_LARGER( maxPbufferWidth
);
1228 PREFER_LARGER( maxPbufferHeight
);
1229 PREFER_LARGER( maxPbufferPixels
);
1236 * Selects and sorts a subset of the supplied configs based on the attributes.
1237 * This function forms to basis of \c glXChooseVisual, \c glXChooseFBConfig,
1238 * and \c glXChooseFBConfigSGIX.
1240 * \param configs Array of pointers to possible configs. The elements of
1241 * this array that do not meet the criteria will be set to
1242 * NULL. The remaining elements will be sorted according to
1243 * the various visual / FBConfig selection rules.
1244 * \param num_configs Number of elements in the \c configs array.
1245 * \param attribList Attributes used select from \c configs. This array is
1246 * terminated by a \c None tag. The array can either take
1247 * the form expected by \c glXChooseVisual (where boolean
1248 * tags do not have a value) or by \c glXChooseFBConfig
1249 * (where every tag has a value).
1250 * \param fbconfig_style_tags Selects whether \c attribList is in
1251 * \c glXChooseVisual style or
1252 * \c glXChooseFBConfig style.
1253 * \returns The number of valid elements left in \c configs.
1255 * \sa glXChooseVisual, glXChooseFBConfig, glXChooseFBConfigSGIX
1258 choose_visual( __GLcontextModes
** configs
, int num_configs
,
1259 const int *attribList
, GLboolean fbconfig_style_tags
)
1261 __GLcontextModes test_config
;
1265 /* This is a fairly direct implementation of the selection method
1266 * described by GLX_SGIX_fbconfig. Start by culling out all the
1267 * configs that are not compatible with the selected parameter
1271 init_fbconfig_for_chooser( & test_config
, fbconfig_style_tags
);
1272 __glXInitializeVisualConfigFromTags( & test_config
, 512,
1273 (const INT32
*) attribList
,
1274 GL_TRUE
, fbconfig_style_tags
);
1277 for ( i
= 0 ; i
< num_configs
; i
++ ) {
1278 if ( fbconfigs_compatible( & test_config
, configs
[i
] ) ) {
1279 configs
[ base
] = configs
[ i
];
1288 if ( base
< num_configs
) {
1289 (void) memset( & configs
[ base
], 0,
1290 sizeof( void * ) * (num_configs
- base
) );
1293 /* After the incompatible configs are removed, the resulting
1294 * list is sorted according to the rules set out in the various
1298 qsort( configs
, base
, sizeof( __GLcontextModes
* ),
1299 (int (*)(const void*, const void*)) fbconfig_compare
);
1307 ** Return the visual that best matches the template. Return None if no
1308 ** visual matches the template.
1310 PUBLIC XVisualInfo
*GLX_PREFIX(glXChooseVisual
)(Display
*dpy
, int screen
,
1313 XVisualInfo
*visualList
= NULL
;
1314 __GLXdisplayPrivate
*priv
;
1315 __GLXscreenConfigs
*psc
;
1316 __GLcontextModes test_config
;
1317 __GLcontextModes
*modes
;
1318 const __GLcontextModes
*best_config
= NULL
;
1321 ** Get a list of all visuals, return if list is empty
1323 if ( GetGLXPrivScreenConfig( dpy
, screen
, & priv
, & psc
) != Success
) {
1329 ** Build a template from the defaults and the attribute list
1330 ** Free visual list and return if an unexpected token is encountered
1332 init_fbconfig_for_chooser( & test_config
, GL_FALSE
);
1333 __glXInitializeVisualConfigFromTags( & test_config
, 512,
1334 (const INT32
*) attribList
,
1335 GL_TRUE
, GL_FALSE
);
1338 ** Eliminate visuals that don't meet minimum requirements
1339 ** Compute a score for those that do
1340 ** Remember which visual, if any, got the highest score
1342 for ( modes
= psc
->configs
; modes
!= NULL
; modes
= modes
->next
) {
1343 if ( fbconfigs_compatible( & test_config
, modes
)
1344 && ((best_config
== NULL
)
1345 || (fbconfig_compare( (const __GLcontextModes
* const * const)&modes
, &best_config
) < 0)) ) {
1346 best_config
= modes
;
1351 ** If no visual is acceptable, return None
1352 ** Otherwise, create an XVisualInfo list with just the selected X visual
1355 if (best_config
!= NULL
) {
1356 XVisualInfo visualTemplate
;
1359 visualTemplate
.screen
= screen
;
1360 visualTemplate
.visualid
= best_config
->visualID
;
1361 visualList
= XGetVisualInfo( dpy
, VisualScreenMask
|VisualIDMask
,
1362 &visualTemplate
, &i
);
1369 PUBLIC
const char *GLX_PREFIX(glXQueryExtensionsString
)( Display
*dpy
,
1372 __GLXscreenConfigs
*psc
;
1373 __GLXdisplayPrivate
*priv
;
1375 if ( GetGLXPrivScreenConfig( dpy
, screen
, & priv
, & psc
) != Success
) {
1379 if (!psc
->effectiveGLXexts
) {
1380 if (!psc
->serverGLXexts
) {
1381 psc
->serverGLXexts
= __glXGetStringFromServer(dpy
, priv
->majorOpcode
,
1382 X_GLXQueryServerString
,
1383 screen
, GLX_EXTENSIONS
);
1386 __glXCalculateUsableExtensions(psc
,
1387 #ifdef GLX_DIRECT_RENDERING
1388 (priv
->driDisplay
.private != NULL
),
1392 priv
->minorVersion
);
1395 return psc
->effectiveGLXexts
;
1398 PUBLIC
const char *GLX_PREFIX(glXGetClientString
)( Display
*dpy
, int name
)
1402 return (__glXGLXClientVendorName
);
1404 return (__glXGLXClientVersion
);
1405 case GLX_EXTENSIONS
:
1406 return (__glXGetClientExtensions());
1412 PUBLIC
const char *GLX_PREFIX(glXQueryServerString
)( Display
*dpy
, int screen
,
1415 __GLXscreenConfigs
*psc
;
1416 __GLXdisplayPrivate
*priv
;
1420 if ( GetGLXPrivScreenConfig( dpy
, screen
, & priv
, & psc
) != Success
) {
1426 str
= & priv
->serverGLXvendor
;
1429 str
= & priv
->serverGLXversion
;
1431 case GLX_EXTENSIONS
:
1432 str
= & psc
->serverGLXexts
;
1438 if ( *str
== NULL
) {
1439 *str
= __glXGetStringFromServer(dpy
, priv
->majorOpcode
,
1440 X_GLXQueryServerString
, screen
, name
);
1446 void __glXClientInfo ( Display
*dpy
, int opcode
)
1448 xGLXClientInfoReq
*req
;
1450 char * ext_str
= __glXGetClientGLExtensionString();
1452 /* Send the glXClientInfo request */
1454 GetReq(GLXClientInfo
,req
);
1455 req
->reqType
= opcode
;
1456 req
->glxCode
= X_GLXClientInfo
;
1457 req
->major
= GLX_MAJOR_VERSION
;
1458 req
->minor
= GLX_MINOR_VERSION
;
1460 size
= strlen( ext_str
) + 1;
1461 req
->length
+= (size
+ 3) >> 2;
1462 req
->numbytes
= size
;
1463 Data(dpy
, ext_str
, size
);
1473 ** EXT_import_context
1476 PUBLIC Display
*glXGetCurrentDisplay(void)
1478 GLXContext gc
= __glXGetCurrentContext();
1479 if (NULL
== gc
) return NULL
;
1480 return gc
->currentDpy
;
1483 PUBLIC
GLX_ALIAS(Display
*, glXGetCurrentDisplayEXT
, (void), (),
1484 glXGetCurrentDisplay
)
1487 * Used internally by libGL to send \c xGLXQueryContextinfoExtReq requests
1490 * \param dpy Display where \c ctx was created.
1491 * \param ctx Context to query.
1492 * \returns \c Success on success. \c GLX_BAD_CONTEXT if \c ctx is invalid,
1493 * or zero if the request failed due to internal problems (i.e.,
1494 * unable to allocate temporary memory, etc.)
1497 * This function dynamically determines whether to use the EXT_import_context
1498 * version of the protocol or the GLX 1.3 version of the protocol.
1500 static int __glXQueryContextInfo(Display
*dpy
, GLXContext ctx
)
1502 __GLXdisplayPrivate
*priv
= __glXInitialize(dpy
);
1503 xGLXQueryContextReply reply
;
1509 return GLX_BAD_CONTEXT
;
1511 opcode
= __glXSetupForCommand(dpy
);
1516 /* Send the glXQueryContextInfoEXT request */
1519 if ( (priv
->majorVersion
> 1) || (priv
->minorVersion
>= 3) ) {
1520 xGLXQueryContextReq
*req
;
1522 GetReq(GLXQueryContext
, req
);
1524 req
->reqType
= opcode
;
1525 req
->glxCode
= X_GLXQueryContext
;
1526 req
->context
= (unsigned int)(ctx
->xid
);
1529 xGLXVendorPrivateReq
*vpreq
;
1530 xGLXQueryContextInfoEXTReq
*req
;
1532 GetReqExtra( GLXVendorPrivate
,
1533 sz_xGLXQueryContextInfoEXTReq
- sz_xGLXVendorPrivateReq
,
1535 req
= (xGLXQueryContextInfoEXTReq
*)vpreq
;
1536 req
->reqType
= opcode
;
1537 req
->glxCode
= X_GLXVendorPrivateWithReply
;
1538 req
->vendorCode
= X_GLXvop_QueryContextInfoEXT
;
1539 req
->context
= (unsigned int)(ctx
->xid
);
1542 _XReply(dpy
, (xReply
*) &reply
, 0, False
);
1544 numValues
= reply
.n
;
1547 else if (numValues
> __GLX_MAX_CONTEXT_PROPS
)
1551 int *propList
, *pProp
;
1555 nPropListBytes
= numValues
<< 3;
1556 propList
= (int *) Xmalloc(nPropListBytes
);
1557 if (NULL
== propList
) {
1560 _XRead(dpy
, (char *)propList
, nPropListBytes
);
1562 for (i
=0; i
< numValues
; i
++) {
1564 case GLX_SHARE_CONTEXT_EXT
:
1565 ctx
->share_xid
= *pProp
++;
1567 case GLX_VISUAL_ID_EXT
:
1568 ctx
->vid
= *pProp
++;
1571 ctx
->screen
= *pProp
++;
1573 case GLX_FBCONFIG_ID
:
1574 ctx
->fbconfigID
= *pProp
++;
1576 case GLX_RENDER_TYPE
:
1577 ctx
->renderType
= *pProp
++;
1584 Xfree((char *)propList
);
1594 GLX_PREFIX(glXQueryContext
)(Display
*dpy
, GLXContext ctx
,
1595 int attribute
, int *value
)
1599 /* get the information from the server if we don't have it already */
1600 if (!ctx
->isDirect
&& (ctx
->vid
== None
)) {
1601 retVal
= __glXQueryContextInfo(dpy
, ctx
);
1602 if (Success
!= retVal
) return retVal
;
1604 switch (attribute
) {
1605 case GLX_SHARE_CONTEXT_EXT
:
1606 *value
= (int)(ctx
->share_xid
);
1608 case GLX_VISUAL_ID_EXT
:
1609 *value
= (int)(ctx
->vid
);
1612 *value
= (int)(ctx
->screen
);
1614 case GLX_FBCONFIG_ID
:
1615 *value
= (int)(ctx
->fbconfigID
);
1617 case GLX_RENDER_TYPE
:
1618 *value
= (int)(ctx
->renderType
);
1621 return GLX_BAD_ATTRIBUTE
;
1626 PUBLIC
GLX_ALIAS( int, glXQueryContextInfoEXT
,
1627 (Display
*dpy
, GLXContext ctx
, int attribute
, int *value
),
1628 (dpy
, ctx
, attribute
, value
),
1631 PUBLIC GLXContextID
glXGetContextIDEXT(const GLXContext ctx
)
1636 PUBLIC GLXContext
GLX_PREFIX(glXImportContextEXT
)(Display
*dpy
,
1637 GLXContextID contextID
)
1641 if (contextID
== None
) {
1644 if (__glXIsDirect(dpy
, contextID
)) {
1648 ctx
= CreateContext(dpy
, NULL
, NULL
, NULL
, False
, contextID
, False
, 0);
1650 if (Success
!= __glXQueryContextInfo(dpy
, ctx
)) {
1657 PUBLIC
void GLX_PREFIX(glXFreeContextEXT
)(Display
*dpy
, GLXContext ctx
)
1659 DestroyContext(dpy
, ctx
);
1665 * GLX 1.3 functions - these are just stubs for now!
1668 PUBLIC GLXFBConfig
*GLX_PREFIX(glXChooseFBConfig
)(Display
*dpy
, int screen
,
1669 const int *attribList
,
1672 __GLcontextModes
** config_list
;
1676 config_list
= (__GLcontextModes
**)
1677 GLX_PREFIX(glXGetFBConfigs
)( dpy
, screen
, & list_size
);
1679 if ( (config_list
!= NULL
) && (list_size
> 0) ) {
1680 list_size
= choose_visual( config_list
, list_size
, attribList
,
1682 if ( list_size
== 0 ) {
1683 XFree( config_list
);
1688 *nitems
= list_size
;
1689 return (GLXFBConfig
*) config_list
;
1693 PUBLIC GLXContext
GLX_PREFIX(glXCreateNewContext
)(Display
*dpy
,
1696 GLXContext shareList
,
1699 return CreateContext( dpy
, NULL
, (__GLcontextModes
*) config
, shareList
,
1700 allowDirect
, None
, True
, renderType
);
1704 PUBLIC GLXDrawable
GLX_PREFIX(glXGetCurrentReadDrawable
)(void)
1706 GLXContext gc
= __glXGetCurrentContext();
1707 return gc
->currentReadable
;
1711 PUBLIC GLXFBConfig
*GLX_PREFIX(glXGetFBConfigs
)(Display
*dpy
, int screen
,
1714 __GLXdisplayPrivate
*priv
= __glXInitialize(dpy
);
1715 __GLcontextModes
** config
= NULL
;
1718 if ( (priv
->screenConfigs
!= NULL
)
1719 && (screen
>= 0) && (screen
<= ScreenCount(dpy
))
1720 && (priv
->screenConfigs
[screen
].configs
!= NULL
)
1721 && (priv
->screenConfigs
[screen
].configs
->fbconfigID
!= GLX_DONT_CARE
) ) {
1722 unsigned num_configs
= 0;
1723 __GLcontextModes
* modes
;
1726 for ( modes
= priv
->screenConfigs
[screen
].configs
1728 ; modes
= modes
->next
) {
1729 if ( modes
->fbconfigID
!= GLX_DONT_CARE
) {
1734 config
= (__GLcontextModes
**) Xmalloc( sizeof(__GLcontextModes
*)
1736 if ( config
!= NULL
) {
1737 *nelements
= num_configs
;
1739 for ( modes
= priv
->screenConfigs
[screen
].configs
1741 ; modes
= modes
->next
) {
1747 return (GLXFBConfig
*) config
;
1751 PUBLIC
int GLX_PREFIX(glXGetFBConfigAttrib
)(Display
*dpy
, GLXFBConfig config
,
1752 int attribute
, int *value
)
1754 __GLcontextModes
* const modes
= ValidateGLXFBConfig( dpy
, config
);
1756 return (modes
!= NULL
)
1757 ? _gl_get_context_mode_data( modes
, attribute
, value
)
1762 PUBLIC XVisualInfo
*GLX_PREFIX(glXGetVisualFromFBConfig
)(Display
*dpy
,
1765 XVisualInfo visualTemplate
;
1766 __GLcontextModes
* fbconfig
= (__GLcontextModes
*) config
;
1770 ** Get a list of all visuals, return if list is empty
1772 visualTemplate
.visualid
= fbconfig
->visualID
;
1773 return XGetVisualInfo(dpy
,VisualIDMask
,&visualTemplate
,&count
);
1778 ** GLX_SGI_make_current_read
1781 PUBLIC
GLX_ALIAS(GLXDrawable
, glXGetCurrentReadDrawableSGI
, (void), (),
1782 glXGetCurrentReadDrawable
)
1786 ** GLX_SGI_swap_control
1788 PUBLIC
int GLX_PREFIX(glXSwapIntervalSGI
)(int interval
)
1790 xGLXVendorPrivateReq
*req
;
1791 GLXContext gc
= __glXGetCurrentContext();
1793 CARD32
* interval_ptr
;
1797 return GLX_BAD_CONTEXT
;
1800 if ( interval
<= 0 ) {
1801 return GLX_BAD_VALUE
;
1804 #ifdef GLX_DIRECT_RENDERING
1805 if ( gc
->isDirect
) {
1806 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs( gc
->currentDpy
,
1808 __DRIdrawable
* const pdraw
= GetDRIDrawable( gc
->currentDpy
,
1809 gc
->currentDrawable
,
1811 if ( __glXExtensionBitIsEnabled( psc
, SGI_swap_control_bit
)
1812 && (pdraw
!= NULL
) ) {
1813 pdraw
->swap_interval
= interval
;
1817 return GLX_BAD_CONTEXT
;
1821 dpy
= gc
->currentDpy
;
1822 opcode
= __glXSetupForCommand(dpy
);
1827 /* Send the glXSwapIntervalSGI request */
1829 GetReqExtra(GLXVendorPrivate
,sizeof(CARD32
),req
);
1830 req
->reqType
= opcode
;
1831 req
->glxCode
= X_GLXVendorPrivate
;
1832 req
->vendorCode
= X_GLXvop_SwapIntervalSGI
;
1833 req
->contextTag
= gc
->currentContextTag
;
1835 interval_ptr
= (CARD32
*) req
+ 1;
1836 *interval_ptr
= interval
;
1847 ** GLX_MESA_swap_control
1849 PUBLIC GLint
GLX_PREFIX(glXSwapIntervalMESA
)(unsigned interval
)
1851 #ifdef GLX_DIRECT_RENDERING
1852 GLXContext gc
= __glXGetCurrentContext();
1854 if ( interval
< 0 ) {
1855 return GLX_BAD_VALUE
;
1858 if ( (gc
!= NULL
) && gc
->isDirect
) {
1859 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs( gc
->currentDpy
,
1862 if ( (psc
!= NULL
) && (psc
->driScreen
.private != NULL
)
1863 && __glXExtensionBitIsEnabled( psc
, MESA_swap_control_bit
) ) {
1864 __DRIdrawable
* const pdraw
=
1865 (*psc
->driScreen
.getDrawable
)(gc
->currentDpy
,
1866 gc
->currentDrawable
,
1867 psc
->driScreen
.private);
1868 if ( pdraw
!= NULL
) {
1869 pdraw
->swap_interval
= interval
;
1878 return GLX_BAD_CONTEXT
;
1881 PUBLIC GLint
GLX_PREFIX(glXGetSwapIntervalMESA
)( void )
1883 #ifdef GLX_DIRECT_RENDERING
1884 GLXContext gc
= __glXGetCurrentContext();
1886 if ( (gc
!= NULL
) && gc
->isDirect
) {
1887 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs( gc
->currentDpy
,
1890 if ( (psc
!= NULL
) && (psc
->driScreen
.private != NULL
)
1891 && __glXExtensionBitIsEnabled( psc
, MESA_swap_control_bit
) ) {
1892 __DRIdrawable
* const pdraw
=
1893 (*psc
->driScreen
.getDrawable
)(gc
->currentDpy
,
1894 gc
->currentDrawable
,
1895 psc
->driScreen
.private);
1896 if ( pdraw
!= NULL
) {
1897 return pdraw
->swap_interval
;
1908 ** GLX_MESA_swap_frame_usage
1911 PUBLIC GLint
GLX_PREFIX(glXBeginFrameTrackingMESA
)(Display
*dpy
,
1912 GLXDrawable drawable
)
1914 int status
= GLX_BAD_CONTEXT
;
1915 #ifdef GLX_DIRECT_RENDERING
1917 __DRIdrawable
* const pdraw
= GetDRIDrawable(dpy
, drawable
, & screen
);
1918 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs(dpy
, screen
);
1920 if ( (pdraw
!= NULL
) && (pdraw
->frameTracking
!= NULL
)
1921 && __glXExtensionBitIsEnabled( psc
, MESA_swap_frame_usage_bit
) ) {
1922 status
= pdraw
->frameTracking( dpy
, pdraw
->private, GL_TRUE
);
1932 PUBLIC GLint
GLX_PREFIX(glXEndFrameTrackingMESA
)(Display
*dpy
,
1933 GLXDrawable drawable
)
1935 int status
= GLX_BAD_CONTEXT
;
1936 #ifdef GLX_DIRECT_RENDERING
1938 __DRIdrawable
* const pdraw
= GetDRIDrawable(dpy
, drawable
, & screen
);
1939 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs(dpy
, screen
);
1941 if ( (pdraw
!= NULL
) && (pdraw
->frameTracking
!= NULL
)
1942 && __glXExtensionBitIsEnabled( psc
, MESA_swap_frame_usage_bit
) ) {
1943 status
= pdraw
->frameTracking( dpy
, pdraw
->private, GL_FALSE
);
1953 PUBLIC GLint
GLX_PREFIX(glXGetFrameUsageMESA
)(Display
*dpy
,
1954 GLXDrawable drawable
,
1957 int status
= GLX_BAD_CONTEXT
;
1958 #ifdef GLX_DIRECT_RENDERING
1960 __DRIdrawable
* const pdraw
= GetDRIDrawable(dpy
, drawable
, & screen
);
1961 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs(dpy
, screen
);
1963 if ( (pdraw
!= NULL
) && (pdraw
->queryFrameTracking
!= NULL
)
1964 && __glXExtensionBitIsEnabled( psc
, MESA_swap_frame_usage_bit
) ) {
1965 int64_t sbc
, missedFrames
;
1966 float lastMissedUsage
;
1968 status
= pdraw
->queryFrameTracking( dpy
, pdraw
->private, &sbc
,
1969 &missedFrames
, &lastMissedUsage
,
1981 PUBLIC GLint
GLX_PREFIX(glXQueryFrameTrackingMESA
)(Display
*dpy
,
1982 GLXDrawable drawable
,
1984 int64_t *missedFrames
,
1985 GLfloat
*lastMissedUsage
)
1987 int status
= GLX_BAD_CONTEXT
;
1988 #ifdef GLX_DIRECT_RENDERING
1990 __DRIdrawable
* const pdraw
= GetDRIDrawable(dpy
, drawable
, & screen
);
1991 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs(dpy
, screen
);
1993 if ( (pdraw
!= NULL
) && (pdraw
->queryFrameTracking
!= NULL
)
1994 && __glXExtensionBitIsEnabled( psc
, MESA_swap_frame_usage_bit
) ) {
1997 status
= pdraw
->queryFrameTracking( dpy
, pdraw
->private, sbc
,
1998 missedFrames
, lastMissedUsage
,
2005 (void) missedFrames
;
2006 (void) lastMissedUsage
;
2013 ** GLX_SGI_video_sync
2015 PUBLIC
int GLX_PREFIX(glXGetVideoSyncSGI
)(unsigned int *count
)
2017 /* FIXME: Looking at the GLX_SGI_video_sync spec in the extension registry,
2018 * FIXME: there should be a GLX encoding for this call. I can find no
2019 * FIXME: documentation for the GLX encoding.
2021 #ifdef GLX_DIRECT_RENDERING
2022 GLXContext gc
= __glXGetCurrentContext();
2025 if ( (gc
!= NULL
) && gc
->isDirect
) {
2026 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs( gc
->currentDpy
,
2028 if ( __glXExtensionBitIsEnabled( psc
, SGI_video_sync_bit
)
2029 && psc
->driScreen
.private && psc
->driScreen
.getMSC
) {
2033 ret
= psc
->driScreen
.getMSC( psc
->driScreen
.private, & temp
);
2034 *count
= (unsigned) temp
;
2035 return (ret
== 0) ? 0 : GLX_BAD_CONTEXT
;
2041 return GLX_BAD_CONTEXT
;
2044 PUBLIC
int GLX_PREFIX(glXWaitVideoSyncSGI
)(int divisor
, int remainder
,
2045 unsigned int *count
)
2047 #ifdef GLX_DIRECT_RENDERING
2048 GLXContext gc
= __glXGetCurrentContext();
2050 if ( divisor
<= 0 || remainder
< 0 )
2051 return GLX_BAD_VALUE
;
2053 if ( (gc
!= NULL
) && gc
->isDirect
) {
2054 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs( gc
->currentDpy
,
2056 if ( __glXExtensionBitIsEnabled( psc
, SGI_video_sync_bit
)
2057 && psc
->driScreen
.private ) {
2058 __DRIdrawable
* const pdraw
=
2059 (*psc
->driScreen
.getDrawable
)(gc
->currentDpy
,
2060 gc
->currentDrawable
,
2061 psc
->driScreen
.private);
2062 if ( (pdraw
!= NULL
) && (pdraw
->waitForMSC
!= NULL
) ) {
2067 ret
= (*pdraw
->waitForMSC
)( gc
->currentDpy
, pdraw
->private,
2068 0, divisor
, remainder
,
2070 *count
= (unsigned) msc
;
2071 return (ret
== 0) ? 0 : GLX_BAD_CONTEXT
;
2078 return GLX_BAD_CONTEXT
;
2083 ** GLX_SGIS_video_source
2087 PUBLIC GLXVideoSourceSGIX
GLX_PREFIX(glXCreateGLXVideoSourceSGIX
)(Display
*dpy
,
2088 int screen
, VLServer server
, VLPath path
,
2089 int nodeClass
, VLNode drainNode
)
2100 PUBLIC
void GLX_PREFIX(glXDestroyGLXVideoSourceSGIX
)(Display
*dpy
,
2101 GLXVideoSourceSGIX src
)
2111 ** GLX_SGIX_fbconfig
2112 ** Many of these functions are aliased to GLX 1.3 entry points in the
2113 ** GLX_functions table.
2116 PUBLIC
GLX_ALIAS(int, glXGetFBConfigAttribSGIX
,
2117 (Display
*dpy
, GLXFBConfigSGIX config
, int attribute
, int *value
),
2118 (dpy
, config
, attribute
, value
),
2119 glXGetFBConfigAttrib
)
2121 PUBLIC
GLX_ALIAS(GLXFBConfigSGIX
*, glXChooseFBConfigSGIX
,
2122 (Display
*dpy
, int screen
, int *attrib_list
, int *nelements
),
2123 (dpy
, screen
, attrib_list
, nelements
),
2126 PUBLIC
GLX_ALIAS(XVisualInfo
*, glXGetVisualFromFBConfigSGIX
,
2127 (Display
* dpy
, GLXFBConfigSGIX config
),
2129 glXGetVisualFromFBConfig
)
2131 PUBLIC GLXPixmap
GLX_PREFIX(glXCreateGLXPixmapWithConfigSGIX
)(Display
*dpy
,
2132 GLXFBConfigSGIX config
, Pixmap pixmap
)
2134 xGLXVendorPrivateWithReplyReq
*vpreq
;
2135 xGLXCreateGLXPixmapWithConfigSGIXReq
*req
;
2136 GLXPixmap xid
= None
;
2138 const __GLcontextModes
* const fbconfig
= (__GLcontextModes
*) config
;
2139 __GLXscreenConfigs
* psc
;
2142 if ( (dpy
== NULL
) || (config
== NULL
) ) {
2146 psc
= GetGLXScreenConfigs( dpy
, fbconfig
->screen
);
2148 && __glXExtensionBitIsEnabled( psc
, SGIX_fbconfig_bit
) ) {
2149 opcode
= __glXSetupForCommand(dpy
);
2154 /* Send the glXCreateGLXPixmapWithConfigSGIX request */
2156 GetReqExtra(GLXVendorPrivateWithReply
,
2157 sz_xGLXCreateGLXPixmapWithConfigSGIXReq
-sz_xGLXVendorPrivateWithReplyReq
,vpreq
);
2158 req
= (xGLXCreateGLXPixmapWithConfigSGIXReq
*)vpreq
;
2159 req
->reqType
= opcode
;
2160 req
->glxCode
= X_GLXVendorPrivateWithReply
;
2161 req
->vendorCode
= X_GLXvop_CreateGLXPixmapWithConfigSGIX
;
2162 req
->screen
= fbconfig
->screen
;
2163 req
->fbconfig
= fbconfig
->fbconfigID
;
2164 req
->pixmap
= pixmap
;
2165 req
->glxpixmap
= xid
= XAllocID(dpy
);
2173 PUBLIC GLXContext
GLX_PREFIX(glXCreateContextWithConfigSGIX
)(Display
*dpy
,
2174 GLXFBConfigSGIX config
, int renderType
,
2175 GLXContext shareList
, Bool allowDirect
)
2177 GLXContext gc
= NULL
;
2178 const __GLcontextModes
* const fbconfig
= (__GLcontextModes
*) config
;
2179 __GLXscreenConfigs
* psc
;
2182 if ( (dpy
== NULL
) || (config
== NULL
) ) {
2186 psc
= GetGLXScreenConfigs( dpy
, fbconfig
->screen
);
2188 && __glXExtensionBitIsEnabled( psc
, SGIX_fbconfig_bit
) ) {
2189 gc
= CreateContext( dpy
, NULL
, (__GLcontextModes
*) config
, shareList
,
2190 allowDirect
, None
, False
, renderType
);
2197 PUBLIC GLXFBConfigSGIX
GLX_PREFIX(glXGetFBConfigFromVisualSGIX
)(Display
*dpy
,
2200 __GLXdisplayPrivate
*priv
;
2201 __GLXscreenConfigs
*psc
;
2203 if ( (GetGLXPrivScreenConfig( dpy
, vis
->screen
, & priv
, & psc
) != Success
)
2204 && __glXExtensionBitIsEnabled( psc
, SGIX_fbconfig_bit
)
2205 && (psc
->configs
->fbconfigID
!= GLX_DONT_CARE
) ) {
2206 return (GLXFBConfigSGIX
) _gl_context_modes_find_visual( psc
->configs
,
2217 PUBLIC
void GLX_PREFIX(glXCushionSGI
)(Display
*dpy
, Window win
, float cushion
)
2226 ** GLX_SGIX_video_resize
2228 PUBLIC
int GLX_PREFIX(glXBindChannelToWindowSGIX
)(Display
*dpy
, int screen
,
2229 int channel
, Window window
)
2238 PUBLIC
int GLX_PREFIX(glXChannelRectSGIX
)(Display
*dpy
, int screen
, int channel
,
2239 int x
, int y
, int w
, int h
)
2251 PUBLIC
int GLX_PREFIX(glXQueryChannelRectSGIX
)(Display
*dpy
, int screen
,
2252 int channel
, int *x
, int *y
,
2265 int GLX_PREFIX(glXQueryChannelDeltasSGIX
)(Display
*dpy
, int screen
, int channel
,
2266 int *dx
, int *dy
, int *dw
, int *dh
)
2278 PUBLIC
int GLX_PREFIX(glXChannelRectSyncSGIX
)(Display
*dpy
, int screen
,
2279 int channel
, GLenum synctype
)
2289 #if defined(_DM_BUFFER_H_)
2291 PUBLIC Bool
GLX_PREFIX(glXAssociateDMPbufferSGIX
)(Display
*dpy
,
2292 GLXPbufferSGIX pbuffer
,
2307 ** GLX_SGIX_swap_group
2309 PUBLIC
void GLX_PREFIX(glXJoinSwapGroupSGIX
)(Display
*dpy
, GLXDrawable drawable
,
2319 ** GLX_SGIX_swap_barrier
2321 PUBLIC
void GLX_PREFIX(glXBindSwapBarrierSGIX
)(Display
*dpy
,
2322 GLXDrawable drawable
,
2330 PUBLIC Bool
GLX_PREFIX(glXQueryMaxSwapBarriersSGIX
)(Display
*dpy
, int screen
,
2341 ** GLX_SUN_get_transparent_index
2343 PUBLIC Status
GLX_PREFIX(glXGetTransparentIndexSUN
)(Display
*dpy
,
2351 (void) pTransparent
;
2357 ** GLX_OML_sync_control
2359 PUBLIC Bool
GLX_PREFIX(glXGetSyncValuesOML
)(Display
*dpy
, GLXDrawable drawable
,
2360 int64_t *ust
, int64_t *msc
, int64_t *sbc
)
2362 #ifdef GLX_DIRECT_RENDERING
2363 __GLXdisplayPrivate
* const priv
= __glXInitialize(dpy
);
2365 if ( priv
!= NULL
) {
2367 __DRIdrawable
* const pdraw
= GetDRIDrawable( dpy
, drawable
, & i
);
2368 __GLXscreenConfigs
* const psc
= &priv
->screenConfigs
[i
];
2370 assert( (pdraw
== NULL
) || (i
!= -1) );
2371 return ( (pdraw
&& pdraw
->getSBC
&& psc
->driScreen
.getMSC
)
2372 && __glXExtensionBitIsEnabled( psc
, OML_sync_control_bit
)
2373 && ((*psc
->driScreen
.getMSC
)( psc
->driScreen
.private, msc
) == 0)
2374 && ((*pdraw
->getSBC
)( dpy
, psc
->driScreen
.private, sbc
) == 0)
2375 && (__glXGetUST( ust
) == 0) );
2389 * Determine the refresh rate of the specified drawable and display.
2391 * \param dpy Display whose refresh rate is to be determined.
2392 * \param drawable Drawable whose refresh rate is to be determined.
2393 * \param numerator Numerator of the refresh rate.
2394 * \param demoninator Denominator of the refresh rate.
2395 * \return If the refresh rate for the specified display and drawable could
2396 * be calculated, True is returned. Otherwise False is returned.
2398 * \note This function is implemented entirely client-side. A lot of other
2399 * functionality is required to export GLX_OML_sync_control, so on
2400 * XFree86 this function can be called for direct-rendering contexts
2401 * when GLX_OML_sync_control appears in the client extension string.
2404 PUBLIC Bool
GLX_PREFIX(glXGetMscRateOML
)(Display
* dpy
, GLXDrawable drawable
,
2405 int32_t * numerator
, int32_t * denominator
)
2407 #if defined( GLX_DIRECT_RENDERING ) && defined( XF86VIDMODE )
2408 __GLXdisplayPrivate
* const priv
= __glXInitialize(dpy
);
2411 if ( priv
!= NULL
) {
2412 XF86VidModeModeLine mode_line
;
2418 GetDRIDrawable( dpy
, drawable
, & screen_num
);
2419 if ( (screen_num
!= -1)
2420 && XF86VidModeQueryVersion( dpy
, & i
, & i
)
2421 && XF86VidModeGetModeLine( dpy
, screen_num
, & dot_clock
,
2423 unsigned n
= dot_clock
* 1000;
2424 unsigned d
= mode_line
.vtotal
* mode_line
.htotal
;
2426 # define V_INTERLACE 0x010
2427 # define V_DBLSCAN 0x020
2429 if ( (mode_line
.flags
& V_INTERLACE
) ) {
2432 else if ( (mode_line
.flags
& V_DBLSCAN
) ) {
2436 /* The OML_sync_control spec requires that if the refresh rate is a
2437 * whole number, that the returned numerator be equal to the refresh
2438 * rate and the denominator be 1.
2441 if ( (n
% d
) == 0 ) {
2446 static const unsigned f
[] = { 13, 11, 7, 5, 3, 2, 0 };
2449 /* This is a poor man's way to reduce a fraction. It's far from
2450 * perfect, but it will work well enough for this situation.
2453 for ( i
= 0 ; f
[i
] != 0 ; i
++ ) {
2454 while ( ((n
% f
[i
]) == 0) && ((d
% f
[i
]) == 0) ) {
2478 PUBLIC
int64_t GLX_PREFIX(glXSwapBuffersMscOML
)(Display
*dpy
,
2479 GLXDrawable drawable
,
2484 #ifdef GLX_DIRECT_RENDERING
2486 __DRIdrawable
*pdraw
= GetDRIDrawable( dpy
, drawable
, & screen
);
2487 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs( dpy
, screen
);
2489 /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE
2490 * error", but it also says "It [glXSwapBuffersMscOML] will return a value
2491 * of -1 if the function failed because of errors detected in the input
2494 if ( divisor
< 0 || remainder
< 0 || target_msc
< 0 )
2496 if ( divisor
> 0 && remainder
>= divisor
)
2499 if ( (pdraw
!= NULL
) && (pdraw
->swapBuffersMSC
!= NULL
)
2500 && __glXExtensionBitIsEnabled( psc
, OML_sync_control_bit
) ) {
2501 return (*pdraw
->swapBuffersMSC
)(dpy
, pdraw
->private, target_msc
,
2502 divisor
, remainder
);
2515 PUBLIC Bool
GLX_PREFIX(glXWaitForMscOML
)(Display
* dpy
, GLXDrawable drawable
,
2516 int64_t target_msc
, int64_t divisor
,
2517 int64_t remainder
, int64_t *ust
,
2518 int64_t *msc
, int64_t *sbc
)
2520 #ifdef GLX_DIRECT_RENDERING
2522 __DRIdrawable
*pdraw
= GetDRIDrawable( dpy
, drawable
, & screen
);
2523 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs( dpy
, screen
);
2526 /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE
2527 * error", but the return type in the spec is Bool.
2529 if ( divisor
< 0 || remainder
< 0 || target_msc
< 0 )
2531 if ( divisor
> 0 && remainder
>= divisor
)
2534 if ( (pdraw
!= NULL
) && (pdraw
->waitForMSC
!= NULL
)
2535 && __glXExtensionBitIsEnabled( psc
, OML_sync_control_bit
) ) {
2536 ret
= (*pdraw
->waitForMSC
)( dpy
, pdraw
->private, target_msc
,
2537 divisor
, remainder
, msc
, sbc
);
2539 /* __glXGetUST returns zero on success and non-zero on failure.
2540 * This function returns True on success and False on failure.
2542 return ( (ret
== 0) && (__glXGetUST( ust
) == 0) );
2558 PUBLIC Bool
GLX_PREFIX(glXWaitForSbcOML
)(Display
* dpy
, GLXDrawable drawable
,
2559 int64_t target_sbc
, int64_t *ust
,
2560 int64_t *msc
, int64_t *sbc
)
2562 #ifdef GLX_DIRECT_RENDERING
2564 __DRIdrawable
*pdraw
= GetDRIDrawable( dpy
, drawable
, & screen
);
2565 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs( dpy
, screen
);
2568 /* The OML_sync_control spec says this should "generate a GLX_BAD_VALUE
2569 * error", but the return type in the spec is Bool.
2571 if ( target_sbc
< 0 )
2574 if ( (pdraw
!= NULL
) && (pdraw
->waitForSBC
!= NULL
)
2575 && __glXExtensionBitIsEnabled( psc
, OML_sync_control_bit
)) {
2576 ret
= (*pdraw
->waitForSBC
)( dpy
, pdraw
->private, target_sbc
, msc
, sbc
);
2578 /* __glXGetUST returns zero on success and non-zero on failure.
2579 * This function returns True on success and False on failure.
2581 return( (ret
== 0) && (__glXGetUST( ust
) == 0) );
2596 * GLX_MESA_allocate_memory
2600 PUBLIC
void *GLX_PREFIX(glXAllocateMemoryMESA
)(Display
*dpy
, int scrn
,
2601 size_t size
, float readFreq
,
2602 float writeFreq
, float priority
)
2604 #ifdef GLX_DIRECT_RENDERING
2605 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs( dpy
, scrn
);
2607 if ( __glXExtensionBitIsEnabled( psc
, MESA_allocate_memory_bit
) ) {
2608 if (psc
&& psc
->driScreen
.private && psc
->driScreen
.allocateMemory
) {
2609 return (*psc
->driScreen
.allocateMemory
)( dpy
, scrn
, size
,
2610 readFreq
, writeFreq
,
2621 #endif /* GLX_DIRECT_RENDERING */
2627 PUBLIC
void GLX_PREFIX(glXFreeMemoryMESA
)(Display
*dpy
, int scrn
, void *pointer
)
2629 #ifdef GLX_DIRECT_RENDERING
2630 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs( dpy
, scrn
);
2632 if ( __glXExtensionBitIsEnabled( psc
, MESA_allocate_memory_bit
) ) {
2633 if (psc
&& psc
->driScreen
.private && psc
->driScreen
.freeMemory
) {
2634 (*psc
->driScreen
.freeMemory
)( dpy
, scrn
, pointer
);
2641 #endif /* GLX_DIRECT_RENDERING */
2645 PUBLIC GLuint
GLX_PREFIX(glXGetMemoryOffsetMESA
)( Display
*dpy
, int scrn
,
2646 const void *pointer
)
2648 #ifdef GLX_DIRECT_RENDERING
2649 __GLXscreenConfigs
* const psc
= GetGLXScreenConfigs( dpy
, scrn
);
2651 if ( __glXExtensionBitIsEnabled( psc
, MESA_allocate_memory_bit
) ) {
2652 if (psc
&& psc
->driScreen
.private && psc
->driScreen
.memoryOffset
) {
2653 return (*psc
->driScreen
.memoryOffset
)( dpy
, scrn
, pointer
);
2660 #endif /* GLX_DIRECT_RENDERING */
2668 * Mesa extension stubs. These will help reduce portability problems.
2673 * Release all buffers associated with the specified GLX drawable.
2676 * This function was intended for stand-alone Mesa. The issue there is that
2677 * the library doesn't get any notification when a window is closed. In
2678 * DRI there is a similar but slightly different issue. When GLX 1.3 is
2679 * supported, there are 3 different functions to destroy a drawable. It
2680 * should be possible to create GLX protocol (or have it determine which
2681 * protocol to use based on the type of the drawable) to have one function
2682 * do the work of 3. For the direct-rendering case, this function could
2683 * just call the driver's \c __DRIdrawableRec::destroyDrawable function.
2684 * This would reduce the frequency with which \c __driGarbageCollectDrawables
2685 * would need to be used. This really should be done as part of the new DRI
2688 * \sa http://oss.sgi.com/projects/ogl-sample/registry/MESA/release_buffers.txt
2689 * __driGarbageCollectDrawables
2690 * glXDestroyGLXPixmap
2691 * glXDestroyPbuffer glXDestroyPixmap glXDestroyWindow
2692 * glXDestroyGLXPbufferSGIX glXDestroyGLXVideoSourceSGIX
2694 PUBLIC Bool
GLX_PREFIX(glXReleaseBuffersMESA
)( Display
*dpy
, GLXDrawable d
)
2702 PUBLIC GLXPixmap
GLX_PREFIX(glXCreateGLXPixmapMESA
)( Display
*dpy
,
2703 XVisualInfo
*visual
,
2715 PUBLIC
void GLX_PREFIX(glXCopySubBufferMESA
)(Display
*dpy
, GLXDrawable drawable
,
2717 int width
, int height
)
2728 PUBLIC Bool
GLX_PREFIX(glXSet3DfxModeMESA
)( int mode
)
2738 * \c strdup is actually not a standard ANSI C or POSIX routine.
2739 * Irix will not define it if ANSI mode is in effect.
2744 __glXstrdup(const char *str
)
2747 copy
= (char *) Xmalloc(strlen(str
) + 1);
2755 ** glXGetProcAddress support
2758 struct name_address_pair
{
2763 #define GLX_FUNCTION(f) { # f, (GLvoid *) f }
2764 #define GLX_FUNCTION2(n,f) { # n, (GLvoid *) f }
2766 static const struct name_address_pair GLX_functions
[] = {
2767 /*** GLX_VERSION_1_0 ***/
2768 GLX_FUNCTION( glXChooseVisual
),
2769 GLX_FUNCTION( glXCopyContext
),
2770 GLX_FUNCTION( glXCreateContext
),
2771 GLX_FUNCTION( glXCreateGLXPixmap
),
2772 GLX_FUNCTION( glXDestroyContext
),
2773 GLX_FUNCTION( glXDestroyGLXPixmap
),
2774 GLX_FUNCTION( glXGetConfig
),
2775 GLX_FUNCTION( glXGetCurrentContext
),
2776 GLX_FUNCTION( glXGetCurrentDrawable
),
2777 GLX_FUNCTION( glXIsDirect
),
2778 GLX_FUNCTION( glXMakeCurrent
),
2779 GLX_FUNCTION( glXQueryExtension
),
2780 GLX_FUNCTION( glXQueryVersion
),
2781 GLX_FUNCTION( glXSwapBuffers
),
2782 GLX_FUNCTION( glXUseXFont
),
2783 GLX_FUNCTION( glXWaitGL
),
2784 GLX_FUNCTION( glXWaitX
),
2786 /*** GLX_VERSION_1_1 ***/
2787 GLX_FUNCTION( glXGetClientString
),
2788 GLX_FUNCTION( glXQueryExtensionsString
),
2789 GLX_FUNCTION( glXQueryServerString
),
2791 /*** GLX_VERSION_1_2 ***/
2792 GLX_FUNCTION( glXGetCurrentDisplay
),
2794 /*** GLX_VERSION_1_3 ***/
2795 GLX_FUNCTION( glXChooseFBConfig
),
2796 GLX_FUNCTION( glXCreateNewContext
),
2797 GLX_FUNCTION( glXCreatePbuffer
),
2798 GLX_FUNCTION( glXCreatePixmap
),
2799 GLX_FUNCTION( glXCreateWindow
),
2800 GLX_FUNCTION( glXDestroyPbuffer
),
2801 GLX_FUNCTION( glXDestroyPixmap
),
2802 GLX_FUNCTION( glXDestroyWindow
),
2803 GLX_FUNCTION( glXGetCurrentReadDrawable
),
2804 GLX_FUNCTION( glXGetFBConfigAttrib
),
2805 GLX_FUNCTION( glXGetFBConfigs
),
2806 GLX_FUNCTION( glXGetSelectedEvent
),
2807 GLX_FUNCTION( glXGetVisualFromFBConfig
),
2808 GLX_FUNCTION( glXMakeContextCurrent
),
2809 GLX_FUNCTION( glXQueryContext
),
2810 GLX_FUNCTION( glXQueryDrawable
),
2811 GLX_FUNCTION( glXSelectEvent
),
2813 /*** GLX_SGI_swap_control ***/
2814 GLX_FUNCTION( glXSwapIntervalSGI
),
2816 /*** GLX_SGI_video_sync ***/
2817 GLX_FUNCTION( glXGetVideoSyncSGI
),
2818 GLX_FUNCTION( glXWaitVideoSyncSGI
),
2820 /*** GLX_SGI_make_current_read ***/
2821 GLX_FUNCTION2( glXMakeCurrentReadSGI
, glXMakeContextCurrent
),
2822 GLX_FUNCTION2( glXGetCurrentReadDrawableSGI
, glXGetCurrentReadDrawable
),
2824 /*** GLX_SGIX_video_source ***/
2826 GLX_FUNCTION( glXCreateGLXVideoSourceSGIX
),
2827 GLX_FUNCTION( glXDestroyGLXVideoSourceSGIX
),
2830 /*** GLX_EXT_import_context ***/
2831 GLX_FUNCTION( glXFreeContextEXT
),
2832 GLX_FUNCTION( glXGetContextIDEXT
),
2833 GLX_FUNCTION2( glXGetCurrentDisplayEXT
, glXGetCurrentDisplay
),
2834 GLX_FUNCTION( glXImportContextEXT
),
2835 GLX_FUNCTION2( glXQueryContextInfoEXT
, glXQueryContext
),
2837 /*** GLX_SGIX_fbconfig ***/
2838 GLX_FUNCTION2( glXGetFBConfigAttribSGIX
, glXGetFBConfigAttrib
),
2839 GLX_FUNCTION2( glXChooseFBConfigSGIX
, glXChooseFBConfig
),
2840 GLX_FUNCTION( glXCreateGLXPixmapWithConfigSGIX
),
2841 GLX_FUNCTION( glXCreateContextWithConfigSGIX
),
2842 GLX_FUNCTION2( glXGetVisualFromFBConfigSGIX
, glXGetVisualFromFBConfig
),
2843 GLX_FUNCTION( glXGetFBConfigFromVisualSGIX
),
2845 /*** GLX_SGIX_pbuffer ***/
2846 GLX_FUNCTION( glXCreateGLXPbufferSGIX
),
2847 GLX_FUNCTION( glXDestroyGLXPbufferSGIX
),
2848 GLX_FUNCTION( glXQueryGLXPbufferSGIX
),
2849 GLX_FUNCTION( glXSelectEventSGIX
),
2850 GLX_FUNCTION( glXGetSelectedEventSGIX
),
2852 /*** GLX_SGI_cushion ***/
2853 GLX_FUNCTION( glXCushionSGI
),
2855 /*** GLX_SGIX_video_resize ***/
2856 GLX_FUNCTION( glXBindChannelToWindowSGIX
),
2857 GLX_FUNCTION( glXChannelRectSGIX
),
2858 GLX_FUNCTION( glXQueryChannelRectSGIX
),
2859 GLX_FUNCTION( glXQueryChannelDeltasSGIX
),
2860 GLX_FUNCTION( glXChannelRectSyncSGIX
),
2862 /*** GLX_SGIX_dmbuffer **/
2863 #if defined(_DM_BUFFER_H_)
2864 GLX_FUNCTION( glXAssociateDMPbufferSGIX
),
2867 /*** GLX_SGIX_swap_group ***/
2868 GLX_FUNCTION( glXJoinSwapGroupSGIX
),
2870 /*** GLX_SGIX_swap_barrier ***/
2871 GLX_FUNCTION( glXBindSwapBarrierSGIX
),
2872 GLX_FUNCTION( glXQueryMaxSwapBarriersSGIX
),
2874 /*** GLX_SUN_get_transparent_index ***/
2875 GLX_FUNCTION( glXGetTransparentIndexSUN
),
2877 /*** GLX_MESA_allocate_memory ***/
2878 GLX_FUNCTION( glXAllocateMemoryMESA
),
2879 GLX_FUNCTION( glXFreeMemoryMESA
),
2880 GLX_FUNCTION( glXGetMemoryOffsetMESA
),
2882 /*** GLX_MESA_copy_sub_buffer ***/
2883 GLX_FUNCTION( glXCopySubBufferMESA
),
2885 /*** GLX_MESA_pixmap_colormap ***/
2886 GLX_FUNCTION( glXCreateGLXPixmapMESA
),
2888 /*** GLX_MESA_release_buffers ***/
2889 GLX_FUNCTION( glXReleaseBuffersMESA
),
2891 /*** GLX_MESA_set_3dfx_mode ***/
2892 GLX_FUNCTION( glXSet3DfxModeMESA
),
2894 /*** GLX_MESA_swap_control ***/
2895 GLX_FUNCTION( glXSwapIntervalMESA
),
2896 GLX_FUNCTION( glXGetSwapIntervalMESA
),
2898 /*** GLX_MESA_swap_frame_usage ***/
2899 GLX_FUNCTION( glXBeginFrameTrackingMESA
),
2900 GLX_FUNCTION( glXEndFrameTrackingMESA
),
2901 GLX_FUNCTION( glXGetFrameUsageMESA
),
2902 GLX_FUNCTION( glXQueryFrameTrackingMESA
),
2904 /*** GLX_ARB_get_proc_address ***/
2905 GLX_FUNCTION( glXGetProcAddressARB
),
2908 GLX_FUNCTION2( glXGetProcAddress
, glXGetProcAddressARB
),
2910 /*** GLX_OML_sync_control ***/
2911 GLX_FUNCTION( glXWaitForSbcOML
),
2912 GLX_FUNCTION( glXWaitForMscOML
),
2913 GLX_FUNCTION( glXSwapBuffersMscOML
),
2914 GLX_FUNCTION( glXGetMscRateOML
),
2915 GLX_FUNCTION( glXGetSyncValuesOML
),
2917 #ifdef GLX_DIRECT_RENDERING
2919 *** Internal functions useful to DRI drivers
2920 *** With this, the DRI drivers shouldn't need dlopen()/dlsym() to
2921 *** access internal libGL functions which may or may not exist.
2923 GLX_FUNCTION( __glXInitialize
),
2924 GLX_FUNCTION( __glXFindDRIScreen
),
2925 GLX_FUNCTION( __glXGetInternalVersion
),
2926 GLX_FUNCTION( __glXWindowExists
),
2927 GLX_FUNCTION2( __glXCreateContextWithConfig
, XF86DRICreateContextWithConfig
),
2928 GLX_FUNCTION2( __glXGetDrawableInfo
, XF86DRIGetDrawableInfo
),
2930 /*** DRI configuration ***/
2931 GLX_FUNCTION( glXGetScreenDriver
),
2932 GLX_FUNCTION( glXGetDriverConfig
),
2934 GLX_FUNCTION( __glXScrEnableExtension
),
2936 GLX_FUNCTION( __glXGetUST
),
2938 GLX_FUNCTION2( __glXCreateContextModes
, _gl_context_modes_create
),
2939 GLX_FUNCTION2( __glXDestroyContextModes
, _gl_context_modes_destroy
),
2942 { NULL
, NULL
} /* end of list */
2946 static const GLvoid
*
2947 get_glx_proc_address(const char *funcName
)
2951 /* try static functions */
2952 for (i
= 0; GLX_functions
[i
].Name
; i
++) {
2953 if (strcmp(GLX_functions
[i
].Name
, funcName
) == 0)
2954 return GLX_functions
[i
].Address
;
2961 #ifndef GLX_BUILT_IN_XMESA
2963 * Get the address of a named GL function. This is the pre-GLX 1.4 name for
2964 * \c glXGetProcAddress.
2966 * \param procName Name of a GL or GLX function.
2967 * \returns A pointer to the named function
2969 * \sa glXGetProcAddress
2971 PUBLIC
void (*glXGetProcAddressARB(const GLubyte
*procName
))( void )
2973 typedef void (*gl_function
)( void );
2977 /* Search the table of GLX and internal functions first. If that
2978 * fails and the supplied name could be a valid core GL name, try
2979 * searching the core GL function table. This check is done to prevent
2980 * DRI based drivers from searching the core GL function table for
2981 * internal API functions.
2984 f
= (gl_function
) get_glx_proc_address((const char *) procName
);
2985 if ( (f
== NULL
) && (procName
[0] == 'g') && (procName
[1] == 'l')
2986 && (procName
[2] != 'X') ) {
2987 f
= (gl_function
) _glapi_get_proc_address((const char *) procName
);
2994 * Get the address of a named GL function. This is the GLX 1.4 name for
2995 * \c glXGetProcAddressARB.
2997 * \param procName Name of a GL or GLX function.
2998 * \returns A pointer to the named function
3000 * \sa glXGetProcAddressARB
3002 PUBLIC
void (*glXGetProcAddress(const GLubyte
*procName
))( void )
3003 #if defined(__GNUC__) && !defined(GLX_ALIAS_UNSUPPORTED)
3004 __attribute__ ((alias ("glXGetProcAddressARB")));
3007 return glXGetProcAddressARB(procName
);
3009 #endif /* __GNUC__ */
3010 #endif /* GLX_BUILT_IN_XMESA */
3013 #ifdef GLX_DIRECT_RENDERING
3015 * Retrieves the verion of the internal libGL API in YYYYMMDD format. This
3016 * might be used by the DRI drivers to determine how new libGL is at runtime.
3017 * Drivers should not call this function directly. They should instead use
3018 * \c glXGetProcAddress to obtain a pointer to the function.
3020 * \returns An 8-digit decimal number representing the internal libGL API in
3023 * \sa glXGetProcAddress, PFNGLXGETINTERNALVERSIONPROC
3025 * \since Internal API version 20021121.
3027 int __glXGetInternalVersion(void)
3030 * 20021121 - Initial version
3031 * 20021128 - Added __glXWindowExists() function
3032 * 20021207 - Added support for dynamic GLX extensions,
3033 * GLX_SGI_swap_control, GLX_SGI_video_sync,
3034 * GLX_OML_sync_control, and GLX_MESA_swap_control.
3035 * Never officially released. Do NOT test against
3036 * this version. Use 20030317 instead.
3037 * 20030317 - Added support GLX_SGIX_fbconfig,
3038 * GLX_MESA_swap_frame_usage, GLX_OML_swap_method,
3039 * GLX_{ARB,SGIS}_multisample, and
3040 * GLX_SGIX_visual_select_group.
3041 * 20030606 - Added support for GLX_SGI_make_current_read.
3042 * 20030813 - Made support for dynamic extensions multi-head aware.
3043 * 20030818 - Added support for GLX_MESA_allocate_memory in place of the
3044 * deprecated GLX_NV_vertex_array_range & GLX_MESA_agp_offset
3046 * 20031201 - Added support for the first round of DRI interface changes.
3047 * Do NOT test against this version! It has binary
3048 * compatibility bugs, use 20040317 instead.
3049 * 20040317 - Added the 'mode' field to __DRIcontextRec.
3050 * 20040415 - Added support for bindContext3 and unbindContext3.
3051 * 20040602 - Add __glXGetDrawableInfo. I though that was there
3059 static Bool windowExistsFlag
;
3061 static int windowExistsErrorHandler(Display
*dpy
, XErrorEvent
*xerr
)
3063 if (xerr
->error_code
== BadWindow
) {
3064 windowExistsFlag
= GL_FALSE
;
3070 * Determine if a window associated with a \c GLXDrawable exists on the
3071 * X-server. This function is not used internally by libGL. It is provided
3072 * as a utility function for DRI drivers.
3073 * Drivers should not call this function directly. They should instead use
3074 * \c glXGetProcAddress to obtain a pointer to the function.
3076 * \param dpy Display associated with the drawable to be queried.
3077 * \param draw \c GLXDrawable to test.
3079 * \returns \c GL_TRUE if a window exists that is associated with \c draw,
3080 * otherwise \c GL_FALSE is returned.
3082 * \warning This function is not currently thread-safe.
3084 * \sa glXGetProcAddress
3086 * \since Internal API version 20021128.
3088 static Bool
__glXWindowExists(Display
*dpy
, GLXDrawable draw
)
3090 XWindowAttributes xwa
;
3091 int (*oldXErrorHandler
)(Display
*, XErrorEvent
*);
3093 XSync(dpy
, GL_FALSE
);
3094 windowExistsFlag
= GL_TRUE
;
3095 oldXErrorHandler
= XSetErrorHandler(windowExistsErrorHandler
);
3096 XGetWindowAttributes(dpy
, draw
, &xwa
); /* dummy request */
3097 XSetErrorHandler(oldXErrorHandler
);
3098 return windowExistsFlag
;
3103 * Get the unadjusted system time (UST). Currently, the UST is measured in
3104 * microseconds since Epoc. The actual resolution of the UST may vary from
3105 * system to system, and the units may vary from release to release.
3106 * Drivers should not call this function directly. They should instead use
3107 * \c glXGetProcAddress to obtain a pointer to the function.
3109 * \param ust Location to store the 64-bit UST
3110 * \returns Zero on success or a negative errno value on failure.
3112 * \sa glXGetProcAddress, PFNGLXGETUSTPROC
3114 * \since Internal API version 20030317.
3116 int __glXGetUST( int64_t * ust
)
3120 if ( ust
== NULL
) {
3124 if ( gettimeofday( & tv
, NULL
) == 0 ) {
3125 ust
[0] = (tv
.tv_sec
* 1000000) + tv
.tv_usec
;
3131 #endif /* GLX_DIRECT_RENDERING */