1 /**************************************************************************
3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
30 * This is an EGL driver that wraps GLX. This gives the benefit of being
31 * completely agnostic of the direct rendering implementation.
33 * Authors: Alan Hourihane <alanh@tungstengraphics.com>
39 * test eglBind/ReleaseTexImage
45 #include <sys/types.h>
51 #include "glxclient.h"
53 #define _EGL_PLATFORM_X
55 #include "eglconfig.h"
56 #include "eglcontext.h"
57 #include "egldisplay.h"
58 #include "egldriver.h"
59 #include "eglglobals.h"
62 #include "eglsurface.h"
66 #define CALLOC_STRUCT(T) (struct T *) calloc(1, sizeof(struct T))
68 static const EGLint all_apis
= (EGL_OPENGL_ES_BIT
71 /* | EGL_OPENGL_BIT */); /* can't do */
75 /* X visual attribs */
79 int redMask
, greenMask
, blueMask
;
83 /* GL visual attribs */
86 int transparentRedValue
;
87 int transparentGreenValue
;
88 int transparentBlueValue
;
89 int transparentAlphaValue
;
90 int transparentIndexValue
;
97 int redSize
, greenSize
, blueSize
, alphaSize
;
100 int accumRedSize
, accumGreenSize
, accumBlueSize
, accumAlphaSize
;
101 int numSamples
, numMultisample
;
105 /** subclass of _EGLDriver */
106 struct GLX_egl_driver
108 _EGLDriver Base
; /**< base class */
110 XVisualInfo
*visuals
;
111 GLXFBConfig
*fbconfigs
;
113 int glx_maj
, glx_min
;
117 /** subclass of _EGLContext */
118 struct GLX_egl_context
120 _EGLContext Base
; /**< base class */
126 /** subclass of _EGLSurface */
127 struct GLX_egl_surface
129 _EGLSurface Base
; /**< base class */
131 GLXDrawable drawable
;
135 /** subclass of _EGLConfig */
136 struct GLX_egl_config
138 _EGLConfig Base
; /**< base class */
142 static struct GLX_egl_driver
*
143 GLX_egl_driver(_EGLDriver
*drv
)
145 return (struct GLX_egl_driver
*) drv
;
148 static struct GLX_egl_context
*
149 GLX_egl_context(_EGLContext
*ctx
)
151 return (struct GLX_egl_context
*) ctx
;
154 static struct GLX_egl_surface
*
155 GLX_egl_surface(_EGLSurface
*surf
)
157 return (struct GLX_egl_surface
*) surf
;
161 get_visual_attribs(Display
*dpy
, XVisualInfo
*vInfo
,
162 struct visual_attribs
*attribs
)
164 const char *ext
= glXQueryExtensionsString(dpy
, vInfo
->screen
);
167 memset(attribs
, 0, sizeof(struct visual_attribs
));
169 attribs
->id
= vInfo
->visualid
;
170 #if defined(__cplusplus) || defined(c_plusplus)
171 attribs
->klass
= vInfo
->c_class
;
173 attribs
->klass
= vInfo
->class;
175 attribs
->depth
= vInfo
->depth
;
176 attribs
->redMask
= vInfo
->red_mask
;
177 attribs
->greenMask
= vInfo
->green_mask
;
178 attribs
->blueMask
= vInfo
->blue_mask
;
179 attribs
->colormapSize
= vInfo
->colormap_size
;
180 attribs
->bitsPerRGB
= vInfo
->bits_per_rgb
;
182 if (glXGetConfig(dpy
, vInfo
, GLX_USE_GL
, &attribs
->supportsGL
) != 0 ||
183 !attribs
->supportsGL
)
185 glXGetConfig(dpy
, vInfo
, GLX_BUFFER_SIZE
, &attribs
->bufferSize
);
186 glXGetConfig(dpy
, vInfo
, GLX_LEVEL
, &attribs
->level
);
187 glXGetConfig(dpy
, vInfo
, GLX_RGBA
, &rgba
);
190 attribs
->render_type
= GLX_RGBA_BIT
;
192 glXGetConfig(dpy
, vInfo
, GLX_DOUBLEBUFFER
, &attribs
->doubleBuffer
);
193 if (!attribs
->doubleBuffer
)
196 glXGetConfig(dpy
, vInfo
, GLX_STEREO
, &attribs
->stereo
);
197 glXGetConfig(dpy
, vInfo
, GLX_AUX_BUFFERS
, &attribs
->auxBuffers
);
198 glXGetConfig(dpy
, vInfo
, GLX_RED_SIZE
, &attribs
->redSize
);
199 glXGetConfig(dpy
, vInfo
, GLX_GREEN_SIZE
, &attribs
->greenSize
);
200 glXGetConfig(dpy
, vInfo
, GLX_BLUE_SIZE
, &attribs
->blueSize
);
201 glXGetConfig(dpy
, vInfo
, GLX_ALPHA_SIZE
, &attribs
->alphaSize
);
202 glXGetConfig(dpy
, vInfo
, GLX_DEPTH_SIZE
, &attribs
->depthSize
);
203 glXGetConfig(dpy
, vInfo
, GLX_STENCIL_SIZE
, &attribs
->stencilSize
);
204 glXGetConfig(dpy
, vInfo
, GLX_ACCUM_RED_SIZE
, &attribs
->accumRedSize
);
205 glXGetConfig(dpy
, vInfo
, GLX_ACCUM_GREEN_SIZE
, &attribs
->accumGreenSize
);
206 glXGetConfig(dpy
, vInfo
, GLX_ACCUM_BLUE_SIZE
, &attribs
->accumBlueSize
);
207 glXGetConfig(dpy
, vInfo
, GLX_ACCUM_ALPHA_SIZE
, &attribs
->accumAlphaSize
);
209 /* get transparent pixel stuff */
210 glXGetConfig(dpy
, vInfo
,GLX_TRANSPARENT_TYPE
, &attribs
->transparentType
);
211 if (attribs
->transparentType
== GLX_TRANSPARENT_RGB
) {
212 glXGetConfig(dpy
, vInfo
, GLX_TRANSPARENT_RED_VALUE
, &attribs
->transparentRedValue
);
213 glXGetConfig(dpy
, vInfo
, GLX_TRANSPARENT_GREEN_VALUE
, &attribs
->transparentGreenValue
);
214 glXGetConfig(dpy
, vInfo
, GLX_TRANSPARENT_BLUE_VALUE
, &attribs
->transparentBlueValue
);
215 glXGetConfig(dpy
, vInfo
, GLX_TRANSPARENT_ALPHA_VALUE
, &attribs
->transparentAlphaValue
);
217 else if (attribs
->transparentType
== GLX_TRANSPARENT_INDEX
) {
218 glXGetConfig(dpy
, vInfo
, GLX_TRANSPARENT_INDEX_VALUE
, &attribs
->transparentIndexValue
);
221 /* multisample attribs */
222 #ifdef GLX_ARB_multisample
223 if (ext
&& strstr(ext
, "GLX_ARB_multisample")) {
224 glXGetConfig(dpy
, vInfo
, GLX_SAMPLE_BUFFERS_ARB
, &attribs
->numMultisample
);
225 glXGetConfig(dpy
, vInfo
, GLX_SAMPLES_ARB
, &attribs
->numSamples
);
229 attribs
->numSamples
= 0;
230 attribs
->numMultisample
= 0;
233 #if defined(GLX_EXT_visual_rating)
234 if (ext
&& strstr(ext
, "GLX_EXT_visual_rating")) {
235 glXGetConfig(dpy
, vInfo
, GLX_VISUAL_CAVEAT_EXT
, &attribs
->visualCaveat
);
238 attribs
->visualCaveat
= GLX_NONE_EXT
;
241 attribs
->visualCaveat
= 0;
247 #ifdef GLX_VERSION_1_3
250 glx_token_to_visual_class(int visual_type
)
252 switch (visual_type
) {
255 case GLX_DIRECT_COLOR
:
257 case GLX_PSEUDO_COLOR
:
259 case GLX_STATIC_COLOR
:
263 case GLX_STATIC_GRAY
:
271 get_fbconfig_attribs(Display
*dpy
, GLXFBConfig fbconfig
,
272 struct visual_attribs
*attribs
)
277 memset(attribs
, 0, sizeof(struct visual_attribs
));
279 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_FBCONFIG_ID
, &fbconfig_id
);
281 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_VISUAL_ID
, &attribs
->id
);
284 attribs
->depth
= vInfo
->depth
;
285 attribs
->redMask
= vInfo
->red_mask
;
286 attribs
->greenMask
= vInfo
->green_mask
;
287 attribs
->blueMask
= vInfo
->blue_mask
;
288 attribs
->colormapSize
= vInfo
->colormap_size
;
289 attribs
->bitsPerRGB
= vInfo
->bits_per_rgb
;
292 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_X_VISUAL_TYPE
, &visual_type
);
293 attribs
->klass
= glx_token_to_visual_class(visual_type
);
295 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_BUFFER_SIZE
, &attribs
->bufferSize
);
296 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_LEVEL
, &attribs
->level
);
297 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_RENDER_TYPE
, &attribs
->render_type
);
298 if (!(attribs
->render_type
& GLX_RGBA_BIT
))
301 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_DOUBLEBUFFER
, &attribs
->doubleBuffer
);
302 if (!attribs
->doubleBuffer
)
305 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_STEREO
, &attribs
->stereo
);
306 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_AUX_BUFFERS
, &attribs
->auxBuffers
);
308 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_RED_SIZE
, &attribs
->redSize
);
309 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_GREEN_SIZE
, &attribs
->greenSize
);
310 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_BLUE_SIZE
, &attribs
->blueSize
);
311 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_ALPHA_SIZE
, &attribs
->alphaSize
);
312 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_DEPTH_SIZE
, &attribs
->depthSize
);
313 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_STENCIL_SIZE
, &attribs
->stencilSize
);
315 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_ACCUM_RED_SIZE
, &attribs
->accumRedSize
);
316 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_ACCUM_GREEN_SIZE
, &attribs
->accumGreenSize
);
317 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_ACCUM_BLUE_SIZE
, &attribs
->accumBlueSize
);
318 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_ACCUM_ALPHA_SIZE
, &attribs
->accumAlphaSize
);
320 /* get transparent pixel stuff */
321 glXGetFBConfigAttrib(dpy
, fbconfig
,GLX_TRANSPARENT_TYPE
, &attribs
->transparentType
);
322 if (attribs
->transparentType
== GLX_TRANSPARENT_RGB
) {
323 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_TRANSPARENT_RED_VALUE
, &attribs
->transparentRedValue
);
324 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_TRANSPARENT_GREEN_VALUE
, &attribs
->transparentGreenValue
);
325 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_TRANSPARENT_BLUE_VALUE
, &attribs
->transparentBlueValue
);
326 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_TRANSPARENT_ALPHA_VALUE
, &attribs
->transparentAlphaValue
);
328 else if (attribs
->transparentType
== GLX_TRANSPARENT_INDEX
) {
329 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_TRANSPARENT_INDEX_VALUE
, &attribs
->transparentIndexValue
);
332 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_SAMPLE_BUFFERS
, &attribs
->numMultisample
);
333 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_SAMPLES
, &attribs
->numSamples
);
335 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_CONFIG_CAVEAT
, &attribs
->visualCaveat
);
337 if (attribs
->id
== 0) {
338 attribs
->id
= fbconfig_id
;
339 return EGL_PBUFFER_BIT
| EGL_PIXMAP_BIT
;
342 return EGL_WINDOW_BIT
;
348 create_configs(_EGLDisplay
*disp
, struct GLX_egl_driver
*GLX_drv
)
350 XVisualInfo theTemplate
;
355 struct visual_attribs attribs
;
357 GLX_drv
->fbconfigs
= NULL
;
359 #ifdef GLX_VERSION_1_3
360 /* get list of all fbconfigs on this screen */
361 GLX_drv
->fbconfigs
= glXGetFBConfigs(disp
->Xdpy
, DefaultScreen(disp
->Xdpy
), &numVisuals
);
363 if (numVisuals
== 0) {
364 GLX_drv
->fbconfigs
= NULL
;
368 for (i
= 0; i
< numVisuals
; i
++) {
369 struct GLX_egl_config
*config
;
372 bit
= get_fbconfig_attribs(disp
->Xdpy
, GLX_drv
->fbconfigs
[i
], &attribs
);
376 config
= CALLOC_STRUCT(GLX_egl_config
);
378 _eglInitConfig(&config
->Base
, (i
+1));
379 SET_CONFIG_ATTRIB(&config
->Base
, EGL_NATIVE_VISUAL_ID
, attribs
.id
);
380 SET_CONFIG_ATTRIB(&config
->Base
, EGL_BUFFER_SIZE
, attribs
.bufferSize
);
381 SET_CONFIG_ATTRIB(&config
->Base
, EGL_RED_SIZE
, attribs
.redSize
);
382 SET_CONFIG_ATTRIB(&config
->Base
, EGL_GREEN_SIZE
, attribs
.greenSize
);
383 SET_CONFIG_ATTRIB(&config
->Base
, EGL_BLUE_SIZE
, attribs
.blueSize
);
384 SET_CONFIG_ATTRIB(&config
->Base
, EGL_ALPHA_SIZE
, attribs
.alphaSize
);
385 SET_CONFIG_ATTRIB(&config
->Base
, EGL_DEPTH_SIZE
, attribs
.depthSize
);
386 SET_CONFIG_ATTRIB(&config
->Base
, EGL_STENCIL_SIZE
, attribs
.stencilSize
);
387 SET_CONFIG_ATTRIB(&config
->Base
, EGL_SAMPLES
, attribs
.numSamples
);
388 SET_CONFIG_ATTRIB(&config
->Base
, EGL_SAMPLE_BUFFERS
, attribs
.numMultisample
);
389 SET_CONFIG_ATTRIB(&config
->Base
, EGL_CONFORMANT
, all_apis
);
390 SET_CONFIG_ATTRIB(&config
->Base
, EGL_RENDERABLE_TYPE
, all_apis
);
391 SET_CONFIG_ATTRIB(&config
->Base
, EGL_SURFACE_TYPE
, bit
);
393 /* XXX possibly other things to init... */
395 _eglAddConfig(disp
, &config
->Base
);
402 /* get list of all visuals on this screen */
403 theTemplate
.screen
= DefaultScreen(disp
->Xdpy
);
404 mask
= VisualScreenMask
;
405 GLX_drv
->visuals
= XGetVisualInfo(disp
->Xdpy
, mask
, &theTemplate
, &numVisuals
);
407 for (i
= 0; i
< numVisuals
; i
++) {
408 struct GLX_egl_config
*config
;
410 if (!get_visual_attribs(disp
->Xdpy
, &GLX_drv
->visuals
[i
], &attribs
))
413 config
= CALLOC_STRUCT(GLX_egl_config
);
415 _eglInitConfig(&config
->Base
, (i
+1));
416 SET_CONFIG_ATTRIB(&config
->Base
, EGL_NATIVE_VISUAL_ID
, attribs
.id
);
417 SET_CONFIG_ATTRIB(&config
->Base
, EGL_BUFFER_SIZE
, attribs
.bufferSize
);
418 SET_CONFIG_ATTRIB(&config
->Base
, EGL_RED_SIZE
, attribs
.redSize
);
419 SET_CONFIG_ATTRIB(&config
->Base
, EGL_GREEN_SIZE
, attribs
.greenSize
);
420 SET_CONFIG_ATTRIB(&config
->Base
, EGL_BLUE_SIZE
, attribs
.blueSize
);
421 SET_CONFIG_ATTRIB(&config
->Base
, EGL_ALPHA_SIZE
, attribs
.alphaSize
);
422 SET_CONFIG_ATTRIB(&config
->Base
, EGL_DEPTH_SIZE
, attribs
.depthSize
);
423 SET_CONFIG_ATTRIB(&config
->Base
, EGL_STENCIL_SIZE
, attribs
.stencilSize
);
424 SET_CONFIG_ATTRIB(&config
->Base
, EGL_SAMPLES
, attribs
.numSamples
);
425 SET_CONFIG_ATTRIB(&config
->Base
, EGL_SAMPLE_BUFFERS
, attribs
.numMultisample
);
426 SET_CONFIG_ATTRIB(&config
->Base
, EGL_CONFORMANT
, all_apis
);
427 SET_CONFIG_ATTRIB(&config
->Base
, EGL_RENDERABLE_TYPE
, all_apis
);
428 SET_CONFIG_ATTRIB(&config
->Base
, EGL_SURFACE_TYPE
,
429 (EGL_WINDOW_BIT
/*| EGL_PBUFFER_BIT | EGL_PIXMAP_BIT*/));
431 /* XXX possibly other things to init... */
433 _eglAddConfig(disp
, &config
->Base
);
441 * Called via eglInitialize(), GLX_drv->API.Initialize().
444 GLX_eglInitialize(_EGLDriver
*drv
, EGLDisplay dpy
,
445 EGLint
*minor
, EGLint
*major
)
447 struct GLX_egl_driver
*GLX_drv
= GLX_egl_driver(drv
);
448 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
450 _eglLog(_EGL_DEBUG
, "GLX: eglInitialize");
453 disp
->Xdpy
= XOpenDisplay(NULL
);
455 _eglLog(_EGL_WARNING
, "GLX: XOpenDisplay failed");
460 glXQueryVersion(disp
->Xdpy
, &GLX_drv
->glx_maj
, &GLX_drv
->glx_min
);
462 GLX_drv
->Base
.Initialized
= EGL_TRUE
;
464 GLX_drv
->Base
.Name
= "GLX";
466 /* we're supporting EGL 1.4 */
470 create_configs(disp
, GLX_drv
);
476 * Do some clean-up that normally occurs in XCloseDisplay().
477 * We do this here because we're about to unload a dynamic library
478 * that has added some per-display extension data and callbacks.
479 * If we don't do this here we'll crash in XCloseDisplay() because it'll
480 * try to call functions that went away when the driver library was unloaded.
483 FreeDisplayExt(Display
*dpy
)
485 _XExtension
*ext
, *next
;
487 for (ext
= dpy
->ext_procs
; ext
; ext
= next
) {
489 if (ext
->close_display
) {
490 ext
->close_display(dpy
, &ext
->codes
);
491 ext
->close_display
= NULL
;
497 dpy
->ext_procs
= NULL
;
499 _XFreeExtData (dpy
->ext_data
);
500 dpy
->ext_data
= NULL
;
504 * Called via eglTerminate(), drv->API.Terminate().
507 GLX_eglTerminate(_EGLDriver
*drv
, EGLDisplay dpy
)
509 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
511 _eglLog(_EGL_DEBUG
, "GLX: eglTerminate");
513 FreeDisplayExt(disp
->Xdpy
);
520 * Called via eglCreateContext(), drv->API.CreateContext().
523 GLX_eglCreateContext(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
,
524 EGLContext share_list
, const EGLint
*attrib_list
)
526 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
527 struct GLX_egl_context
*GLX_ctx
= CALLOC_STRUCT(GLX_egl_context
);
528 struct GLX_egl_driver
*GLX_drv
= GLX_egl_driver(drv
);
529 struct GLX_egl_context
*GLX_ctx_shared
= NULL
;
533 return EGL_NO_CONTEXT
;
535 conf
= _eglLookupConfig(drv
, dpy
, config
);
538 if (!_eglInitContext(drv
, &GLX_ctx
->Base
, conf
, attrib_list
)) {
540 return EGL_NO_CONTEXT
;
543 if (share_list
!= EGL_NO_CONTEXT
) {
544 _EGLContext
*shareCtx
= _eglLookupContext(share_list
);
546 _eglError(EGL_BAD_CONTEXT
, "eglCreateContext(share_list)");
549 GLX_ctx_shared
= GLX_egl_context(shareCtx
);
552 #ifdef GLX_VERSION_1_3
553 if (GLX_drv
->fbconfigs
)
554 GLX_ctx
->context
= glXCreateNewContext(disp
->Xdpy
, GLX_drv
->fbconfigs
[(int)config
-1], GLX_RGBA_TYPE
, GLX_ctx_shared
? GLX_ctx_shared
->context
: NULL
, GL_TRUE
);
557 GLX_ctx
->context
= glXCreateContext(disp
->Xdpy
, &GLX_drv
->visuals
[(int)config
-1], GLX_ctx_shared
? GLX_ctx_shared
->context
: NULL
, GL_TRUE
);
558 if (!GLX_ctx
->context
)
562 /* (maybe?) need to have a direct rendering context */
563 if (!glXIsDirect(disp
->Xdpy
, GLX_ctx
->context
))
567 return _eglLinkContext(&GLX_ctx
->Base
, disp
);
572 * Called via eglMakeCurrent(), drv->API.MakeCurrent().
575 GLX_eglMakeCurrent(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface d
,
576 EGLSurface r
, EGLContext context
)
578 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
579 _EGLContext
*ctx
= _eglLookupContext(context
);
580 _EGLSurface
*dsurf
= _eglLookupSurface(d
);
581 _EGLSurface
*rsurf
= _eglLookupSurface(r
);
582 struct GLX_egl_surface
*GLX_dsurf
= GLX_egl_surface(dsurf
);
583 struct GLX_egl_surface
*GLX_rsurf
= GLX_egl_surface(rsurf
);
584 struct GLX_egl_context
*GLX_ctx
= GLX_egl_context(ctx
);
586 if (!_eglMakeCurrent(drv
, dpy
, d
, r
, context
))
589 #ifdef GLX_VERSION_1_3
590 if (!glXMakeContextCurrent(disp
->Xdpy
, GLX_dsurf
? GLX_dsurf
->drawable
: 0, GLX_rsurf
? GLX_rsurf
->drawable
: 0, GLX_ctx
? GLX_ctx
->context
: NULL
))
592 if (!glXMakeCurrent(disp
->Xdpy
, GLX_dsurf
? GLX_dsurf
->drawable
: 0, GLX_ctx
? GLX_ctx
->context
: NULL
))
598 /** Get size of given window */
600 get_drawable_size(Display
*dpy
, Drawable d
, uint
*width
, uint
*height
)
605 unsigned int w
, h
, bw
, depth
;
606 stat
= XGetGeometry(dpy
, d
, &root
, &xpos
, &ypos
, &w
, &h
, &bw
, &depth
);
613 * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
616 GLX_eglCreateWindowSurface(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
,
617 NativeWindowType window
, const EGLint
*attrib_list
)
619 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
620 struct GLX_egl_surface
*GLX_surf
;
624 conf
= _eglLookupConfig(drv
, dpy
, config
);
627 GLX_surf
= CALLOC_STRUCT(GLX_egl_surface
);
629 return EGL_NO_SURFACE
;
631 if (!_eglInitSurface(drv
, &GLX_surf
->Base
, EGL_WINDOW_BIT
,
632 conf
, attrib_list
)) {
637 _eglLinkSurface(&GLX_surf
->Base
, disp
);
639 GLX_surf
->drawable
= window
;
640 get_drawable_size(disp
->Xdpy
, window
, &width
, &height
);
641 GLX_surf
->Base
.Width
= width
;
642 GLX_surf
->Base
.Height
= height
;
644 return _eglGetSurfaceHandle(&GLX_surf
->Base
);
647 #ifdef GLX_VERSION_1_3
649 GLX_eglCreatePixmapSurface(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
,
650 NativePixmapType pixmap
, const EGLint
*attrib_list
)
652 struct GLX_egl_driver
*GLX_drv
= GLX_egl_driver(drv
);
653 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
654 struct GLX_egl_surface
*GLX_surf
;
658 conf
= _eglLookupConfig(drv
, dpy
, config
);
661 GLX_surf
= CALLOC_STRUCT(GLX_egl_surface
);
663 return EGL_NO_SURFACE
;
665 if (!_eglInitSurface(drv
, &GLX_surf
->Base
, EGL_PIXMAP_BIT
,
666 conf
, attrib_list
)) {
671 _eglLinkSurface(&GLX_surf
->Base
, disp
);
673 for (i
= 0; attrib_list
&& attrib_list
[i
] != EGL_NONE
; i
++) {
674 switch (attrib_list
[i
]) {
675 /* no attribs at this time */
677 _eglError(EGL_BAD_ATTRIBUTE
, "eglCreatePixmapSurface");
678 return EGL_NO_SURFACE
;
682 GLX_surf
->drawable
= glXCreatePixmap(disp
->Xdpy
, GLX_drv
->fbconfigs
[(int)config
-1], pixmap
, NULL
);
684 return _eglGetSurfaceHandle(&GLX_surf
->Base
);
688 GLX_eglCreatePbufferSurface(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
,
689 const EGLint
*attrib_list
)
691 struct GLX_egl_driver
*GLX_drv
= GLX_egl_driver(drv
);
692 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
693 struct GLX_egl_surface
*GLX_surf
;
698 conf
= _eglLookupConfig(drv
, dpy
, config
);
701 GLX_surf
= CALLOC_STRUCT(GLX_egl_surface
);
703 return EGL_NO_SURFACE
;
705 if (!_eglInitSurface(drv
, &GLX_surf
->Base
, EGL_PBUFFER_BIT
,
706 conf
, attrib_list
)) {
708 return EGL_NO_SURFACE
;
711 _eglLinkSurface(&GLX_surf
->Base
, disp
);
713 while(attrib_list
[i
] != EGL_NONE
) {
714 switch (attrib_list
[i
]) {
716 attribs
[j
++] = GLX_PBUFFER_WIDTH
;
717 attribs
[j
++] = attrib_list
[i
+1];
720 attribs
[j
++] = GLX_PBUFFER_HEIGHT
;
721 attribs
[j
++] = attrib_list
[i
+1];
728 GLX_surf
->drawable
= glXCreatePbuffer(disp
->Xdpy
, GLX_drv
->fbconfigs
[(int)config
-1], attribs
);
730 return _eglGetSurfaceHandle(&GLX_surf
->Base
);
735 GLX_eglDestroySurface(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface surface
)
737 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
738 _EGLSurface
*surf
= _eglLookupSurface(surface
);
741 _eglUnlinkSurface(surf
);
742 if (!_eglIsSurfaceBound(surf
))
748 _eglError(EGL_BAD_SURFACE
, "eglDestroySurface");
755 GLX_eglBindTexImage(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface surface
,
758 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
759 _EGLSurface
*surf
= _eglLookupSurface(surface
);
760 struct GLX_egl_surface
*GLX_surf
= GLX_egl_surface(surf
);
763 glXBindTexImageEXT(disp
->Xdpy
, GLX_surf
->drawable
, GLX_FRONT_LEFT_EXT
, NULL
);
770 GLX_eglReleaseTexImage(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface surface
,
773 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
774 _EGLSurface
*surf
= _eglLookupSurface(surface
);
775 struct GLX_egl_surface
*GLX_surf
= GLX_egl_surface(surf
);
778 glXReleaseTexImageEXT(disp
->Xdpy
, GLX_surf
->drawable
, GLX_FRONT_LEFT_EXT
);
785 GLX_eglSwapBuffers(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface draw
)
787 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
788 _EGLSurface
*surf
= _eglLookupSurface(draw
);
789 struct GLX_egl_surface
*GLX_surf
= GLX_egl_surface(surf
);
791 _eglLog(_EGL_DEBUG
, "GLX: EGL SwapBuffers 0x%x",draw
);
793 /* error checking step: */
794 if (!_eglSwapBuffers(drv
, dpy
, draw
))
797 glXSwapBuffers(disp
->Xdpy
, GLX_surf
->drawable
);
803 * Called from eglGetProcAddress() via drv->API.GetProcAddress().
806 GLX_eglGetProcAddress(const char *procname
)
808 /* This is a bit of a hack to get at the gallium/Mesa state tracker
809 * function st_get_proc_address(). This will probably change at
812 _EGLProc (*get_proc_addr
)(const char *procname
);
813 get_proc_addr
= dlsym(NULL
, "st_get_proc_address");
815 return get_proc_addr(procname
);
817 get_proc_addr
= glXGetProcAddress((const GLubyte
*)procname
);
819 return get_proc_addr(procname
);
821 return (_EGLProc
)dlsym(NULL
, procname
);
826 * This is the main entrypoint into the driver, called by libEGL.
827 * Create a new _EGLDriver object and init its dispatch table.
830 _eglMain(_EGLDisplay
*disp
, const char *args
)
832 struct GLX_egl_driver
*GLX_drv
= CALLOC_STRUCT(GLX_egl_driver
);
834 int maj
= 0, min
= 0;
839 _eglInitDriverFallbacks(&GLX_drv
->Base
);
840 GLX_drv
->Base
.API
.Initialize
= GLX_eglInitialize
;
841 GLX_drv
->Base
.API
.Terminate
= GLX_eglTerminate
;
842 GLX_drv
->Base
.API
.CreateContext
= GLX_eglCreateContext
;
843 GLX_drv
->Base
.API
.MakeCurrent
= GLX_eglMakeCurrent
;
844 GLX_drv
->Base
.API
.CreateWindowSurface
= GLX_eglCreateWindowSurface
;
845 #ifdef GLX_VERSION_1_3
846 if (GLX_drv
->glx_maj
== 1 && GLX_drv
->glx_min
>= 3) {
847 GLX_drv
->Base
.API
.CreatePixmapSurface
= GLX_eglCreatePixmapSurface
;
848 GLX_drv
->Base
.API
.CreatePbufferSurface
= GLX_eglCreatePbufferSurface
;
849 printf("GLX: Pbuffer and Pixmap support\n");
851 printf("GLX: No pbuffer or pixmap support\n");
854 GLX_drv
->Base
.API
.DestroySurface
= GLX_eglDestroySurface
;
855 GLX_drv
->Base
.API
.BindTexImage
= GLX_eglBindTexImage
;
856 GLX_drv
->Base
.API
.ReleaseTexImage
= GLX_eglReleaseTexImage
;
857 GLX_drv
->Base
.API
.SwapBuffers
= GLX_eglSwapBuffers
;
858 GLX_drv
->Base
.API
.GetProcAddress
= GLX_eglGetProcAddress
;
860 GLX_drv
->Base
.ClientAPIsMask
= all_apis
;
861 GLX_drv
->Base
.Name
= "GLX";
863 _eglLog(_EGL_DEBUG
, "GLX: main(%s)", args
);
865 /* set new DRI path to pick up EGL version (which doesn't contain any mesa
866 * code), but don't override if one is already set.
868 env
= getenv("LIBGL_DRIVERS_PATH");
870 if (!strstr(env
, "egl")) {
871 sprintf(env
, "%s/egl", env
);
872 setenv("LIBGL_DRIVERS_PATH", env
, 1);
875 setenv("LIBGL_DRIVERS_PATH", DEFAULT_DRIVER_DIR
"/egl", 0);
877 return &GLX_drv
->Base
;