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 #include "eglconfig.h"
54 #include "eglcontext.h"
55 #include "egldisplay.h"
56 #include "egldriver.h"
57 #include "eglglobals.h"
59 #include "eglsurface.h"
63 #define CALLOC_STRUCT(T) (struct T *) calloc(1, sizeof(struct T))
65 static const EGLint all_apis
= (EGL_OPENGL_ES_BIT
68 /* | EGL_OPENGL_BIT */); /* can't do */
72 /* X visual attribs */
76 int redMask
, greenMask
, blueMask
;
80 /* GL visual attribs */
83 int transparentRedValue
;
84 int transparentGreenValue
;
85 int transparentBlueValue
;
86 int transparentAlphaValue
;
87 int transparentIndexValue
;
94 int redSize
, greenSize
, blueSize
, alphaSize
;
97 int accumRedSize
, accumGreenSize
, accumBlueSize
, accumAlphaSize
;
98 int numSamples
, numMultisample
;
102 /** subclass of _EGLDriver */
103 struct GLX_egl_driver
105 _EGLDriver Base
; /**< base class */
109 /** driver data of _EGLDisplay */
110 struct GLX_egl_display
113 XVisualInfo
*visuals
;
114 GLXFBConfig
*fbconfigs
;
116 int glx_maj
, glx_min
;
120 /** subclass of _EGLContext */
121 struct GLX_egl_context
123 _EGLContext Base
; /**< base class */
129 /** subclass of _EGLSurface */
130 struct GLX_egl_surface
132 _EGLSurface Base
; /**< base class */
134 GLXDrawable drawable
;
138 /** subclass of _EGLConfig */
139 struct GLX_egl_config
141 _EGLConfig Base
; /**< base class */
146 static struct GLX_egl_driver
*
147 GLX_egl_driver(_EGLDriver
*drv
)
149 return (struct GLX_egl_driver
*) drv
;
152 static struct GLX_egl_display
*
153 GLX_egl_display(_EGLDisplay
*dpy
)
155 return (struct GLX_egl_display
*) dpy
->DriverData
;
158 static struct GLX_egl_context
*
159 GLX_egl_context(_EGLContext
*ctx
)
161 return (struct GLX_egl_context
*) ctx
;
164 static struct GLX_egl_surface
*
165 GLX_egl_surface(_EGLSurface
*surf
)
167 return (struct GLX_egl_surface
*) surf
;
171 GLX_egl_config_index(_EGLConfig
*conf
)
173 return ((struct GLX_egl_config
*) conf
)->index
;
177 get_visual_attribs(Display
*dpy
, XVisualInfo
*vInfo
,
178 struct visual_attribs
*attribs
)
180 const char *ext
= glXQueryExtensionsString(dpy
, vInfo
->screen
);
183 memset(attribs
, 0, sizeof(struct visual_attribs
));
185 attribs
->id
= vInfo
->visualid
;
186 #if defined(__cplusplus) || defined(c_plusplus)
187 attribs
->klass
= vInfo
->c_class
;
189 attribs
->klass
= vInfo
->class;
191 attribs
->depth
= vInfo
->depth
;
192 attribs
->redMask
= vInfo
->red_mask
;
193 attribs
->greenMask
= vInfo
->green_mask
;
194 attribs
->blueMask
= vInfo
->blue_mask
;
195 attribs
->colormapSize
= vInfo
->colormap_size
;
196 attribs
->bitsPerRGB
= vInfo
->bits_per_rgb
;
198 if (glXGetConfig(dpy
, vInfo
, GLX_USE_GL
, &attribs
->supportsGL
) != 0 ||
199 !attribs
->supportsGL
)
201 glXGetConfig(dpy
, vInfo
, GLX_BUFFER_SIZE
, &attribs
->bufferSize
);
202 glXGetConfig(dpy
, vInfo
, GLX_LEVEL
, &attribs
->level
);
203 glXGetConfig(dpy
, vInfo
, GLX_RGBA
, &rgba
);
206 attribs
->render_type
= GLX_RGBA_BIT
;
208 glXGetConfig(dpy
, vInfo
, GLX_DOUBLEBUFFER
, &attribs
->doubleBuffer
);
209 if (!attribs
->doubleBuffer
)
212 glXGetConfig(dpy
, vInfo
, GLX_STEREO
, &attribs
->stereo
);
213 glXGetConfig(dpy
, vInfo
, GLX_AUX_BUFFERS
, &attribs
->auxBuffers
);
214 glXGetConfig(dpy
, vInfo
, GLX_RED_SIZE
, &attribs
->redSize
);
215 glXGetConfig(dpy
, vInfo
, GLX_GREEN_SIZE
, &attribs
->greenSize
);
216 glXGetConfig(dpy
, vInfo
, GLX_BLUE_SIZE
, &attribs
->blueSize
);
217 glXGetConfig(dpy
, vInfo
, GLX_ALPHA_SIZE
, &attribs
->alphaSize
);
218 glXGetConfig(dpy
, vInfo
, GLX_DEPTH_SIZE
, &attribs
->depthSize
);
219 glXGetConfig(dpy
, vInfo
, GLX_STENCIL_SIZE
, &attribs
->stencilSize
);
220 glXGetConfig(dpy
, vInfo
, GLX_ACCUM_RED_SIZE
, &attribs
->accumRedSize
);
221 glXGetConfig(dpy
, vInfo
, GLX_ACCUM_GREEN_SIZE
, &attribs
->accumGreenSize
);
222 glXGetConfig(dpy
, vInfo
, GLX_ACCUM_BLUE_SIZE
, &attribs
->accumBlueSize
);
223 glXGetConfig(dpy
, vInfo
, GLX_ACCUM_ALPHA_SIZE
, &attribs
->accumAlphaSize
);
225 /* get transparent pixel stuff */
226 glXGetConfig(dpy
, vInfo
,GLX_TRANSPARENT_TYPE
, &attribs
->transparentType
);
227 if (attribs
->transparentType
== GLX_TRANSPARENT_RGB
) {
228 glXGetConfig(dpy
, vInfo
, GLX_TRANSPARENT_RED_VALUE
, &attribs
->transparentRedValue
);
229 glXGetConfig(dpy
, vInfo
, GLX_TRANSPARENT_GREEN_VALUE
, &attribs
->transparentGreenValue
);
230 glXGetConfig(dpy
, vInfo
, GLX_TRANSPARENT_BLUE_VALUE
, &attribs
->transparentBlueValue
);
231 glXGetConfig(dpy
, vInfo
, GLX_TRANSPARENT_ALPHA_VALUE
, &attribs
->transparentAlphaValue
);
233 else if (attribs
->transparentType
== GLX_TRANSPARENT_INDEX
) {
234 glXGetConfig(dpy
, vInfo
, GLX_TRANSPARENT_INDEX_VALUE
, &attribs
->transparentIndexValue
);
237 /* multisample attribs */
238 #ifdef GLX_ARB_multisample
239 if (ext
&& strstr(ext
, "GLX_ARB_multisample")) {
240 glXGetConfig(dpy
, vInfo
, GLX_SAMPLE_BUFFERS_ARB
, &attribs
->numMultisample
);
241 glXGetConfig(dpy
, vInfo
, GLX_SAMPLES_ARB
, &attribs
->numSamples
);
245 attribs
->numSamples
= 0;
246 attribs
->numMultisample
= 0;
249 #if defined(GLX_EXT_visual_rating)
250 if (ext
&& strstr(ext
, "GLX_EXT_visual_rating")) {
251 glXGetConfig(dpy
, vInfo
, GLX_VISUAL_CAVEAT_EXT
, &attribs
->visualCaveat
);
254 attribs
->visualCaveat
= GLX_NONE_EXT
;
257 attribs
->visualCaveat
= 0;
263 #ifdef GLX_VERSION_1_3
266 glx_token_to_visual_class(int visual_type
)
268 switch (visual_type
) {
271 case GLX_DIRECT_COLOR
:
273 case GLX_PSEUDO_COLOR
:
275 case GLX_STATIC_COLOR
:
279 case GLX_STATIC_GRAY
:
288 get_fbconfig_attribs(Display
*dpy
, GLXFBConfig fbconfig
,
289 struct visual_attribs
*attribs
)
294 memset(attribs
, 0, sizeof(struct visual_attribs
));
296 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_FBCONFIG_ID
, &fbconfig_id
);
298 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_VISUAL_ID
, &attribs
->id
);
301 attribs
->depth
= vInfo
->depth
;
302 attribs
->redMask
= vInfo
->red_mask
;
303 attribs
->greenMask
= vInfo
->green_mask
;
304 attribs
->blueMask
= vInfo
->blue_mask
;
305 attribs
->colormapSize
= vInfo
->colormap_size
;
306 attribs
->bitsPerRGB
= vInfo
->bits_per_rgb
;
309 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_X_VISUAL_TYPE
, &visual_type
);
310 attribs
->klass
= glx_token_to_visual_class(visual_type
);
312 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_BUFFER_SIZE
, &attribs
->bufferSize
);
313 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_LEVEL
, &attribs
->level
);
314 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_RENDER_TYPE
, &attribs
->render_type
);
315 if (!(attribs
->render_type
& GLX_RGBA_BIT
))
318 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_DOUBLEBUFFER
, &attribs
->doubleBuffer
);
319 if (!attribs
->doubleBuffer
)
322 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_STEREO
, &attribs
->stereo
);
323 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_AUX_BUFFERS
, &attribs
->auxBuffers
);
325 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_RED_SIZE
, &attribs
->redSize
);
326 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_GREEN_SIZE
, &attribs
->greenSize
);
327 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_BLUE_SIZE
, &attribs
->blueSize
);
328 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_ALPHA_SIZE
, &attribs
->alphaSize
);
329 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_DEPTH_SIZE
, &attribs
->depthSize
);
330 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_STENCIL_SIZE
, &attribs
->stencilSize
);
332 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_ACCUM_RED_SIZE
, &attribs
->accumRedSize
);
333 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_ACCUM_GREEN_SIZE
, &attribs
->accumGreenSize
);
334 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_ACCUM_BLUE_SIZE
, &attribs
->accumBlueSize
);
335 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_ACCUM_ALPHA_SIZE
, &attribs
->accumAlphaSize
);
337 /* get transparent pixel stuff */
338 glXGetFBConfigAttrib(dpy
, fbconfig
,GLX_TRANSPARENT_TYPE
, &attribs
->transparentType
);
339 if (attribs
->transparentType
== GLX_TRANSPARENT_RGB
) {
340 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_TRANSPARENT_RED_VALUE
, &attribs
->transparentRedValue
);
341 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_TRANSPARENT_GREEN_VALUE
, &attribs
->transparentGreenValue
);
342 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_TRANSPARENT_BLUE_VALUE
, &attribs
->transparentBlueValue
);
343 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_TRANSPARENT_ALPHA_VALUE
, &attribs
->transparentAlphaValue
);
345 else if (attribs
->transparentType
== GLX_TRANSPARENT_INDEX
) {
346 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_TRANSPARENT_INDEX_VALUE
, &attribs
->transparentIndexValue
);
349 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_SAMPLE_BUFFERS
, &attribs
->numMultisample
);
350 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_SAMPLES
, &attribs
->numSamples
);
352 glXGetFBConfigAttrib(dpy
, fbconfig
, GLX_CONFIG_CAVEAT
, &attribs
->visualCaveat
);
354 if (attribs
->id
== 0) {
355 attribs
->id
= fbconfig_id
;
356 return EGL_PBUFFER_BIT
| EGL_PIXMAP_BIT
;
359 return EGL_WINDOW_BIT
;
365 create_configs(_EGLDisplay
*disp
, struct GLX_egl_display
*GLX_dpy
)
367 XVisualInfo theTemplate
;
371 struct visual_attribs attribs
;
373 GLX_dpy
->fbconfigs
= NULL
;
375 #ifdef GLX_VERSION_1_3
376 /* get list of all fbconfigs on this screen */
377 GLX_dpy
->fbconfigs
= glXGetFBConfigs(GLX_dpy
->dpy
, DefaultScreen(GLX_dpy
->dpy
), &numVisuals
);
379 if (numVisuals
== 0) {
380 GLX_dpy
->fbconfigs
= NULL
;
384 for (i
= 0; i
< numVisuals
; i
++) {
385 struct GLX_egl_config
*config
;
388 bit
= get_fbconfig_attribs(GLX_dpy
->dpy
, GLX_dpy
->fbconfigs
[i
], &attribs
);
392 config
= CALLOC_STRUCT(GLX_egl_config
);
395 _eglInitConfig(&config
->Base
, (i
+1));
396 SET_CONFIG_ATTRIB(&config
->Base
, EGL_NATIVE_VISUAL_ID
, attribs
.id
);
397 SET_CONFIG_ATTRIB(&config
->Base
, EGL_BUFFER_SIZE
, attribs
.bufferSize
);
398 SET_CONFIG_ATTRIB(&config
->Base
, EGL_RED_SIZE
, attribs
.redSize
);
399 SET_CONFIG_ATTRIB(&config
->Base
, EGL_GREEN_SIZE
, attribs
.greenSize
);
400 SET_CONFIG_ATTRIB(&config
->Base
, EGL_BLUE_SIZE
, attribs
.blueSize
);
401 SET_CONFIG_ATTRIB(&config
->Base
, EGL_ALPHA_SIZE
, attribs
.alphaSize
);
402 SET_CONFIG_ATTRIB(&config
->Base
, EGL_DEPTH_SIZE
, attribs
.depthSize
);
403 SET_CONFIG_ATTRIB(&config
->Base
, EGL_STENCIL_SIZE
, attribs
.stencilSize
);
404 SET_CONFIG_ATTRIB(&config
->Base
, EGL_SAMPLES
, attribs
.numSamples
);
405 SET_CONFIG_ATTRIB(&config
->Base
, EGL_SAMPLE_BUFFERS
, attribs
.numMultisample
);
406 SET_CONFIG_ATTRIB(&config
->Base
, EGL_CONFORMANT
, all_apis
);
407 SET_CONFIG_ATTRIB(&config
->Base
, EGL_RENDERABLE_TYPE
, all_apis
);
408 SET_CONFIG_ATTRIB(&config
->Base
, EGL_SURFACE_TYPE
, bit
);
410 /* XXX possibly other things to init... */
412 _eglAddConfig(disp
, &config
->Base
);
419 /* get list of all visuals on this screen */
420 theTemplate
.screen
= DefaultScreen(GLX_dpy
->dpy
);
421 mask
= VisualScreenMask
;
422 GLX_dpy
->visuals
= XGetVisualInfo(GLX_dpy
->dpy
, mask
, &theTemplate
, &numVisuals
);
424 for (i
= 0; i
< numVisuals
; i
++) {
425 struct GLX_egl_config
*config
;
427 if (!get_visual_attribs(GLX_dpy
->dpy
, &GLX_dpy
->visuals
[i
], &attribs
))
430 config
= CALLOC_STRUCT(GLX_egl_config
);
433 _eglInitConfig(&config
->Base
, (i
+1));
434 SET_CONFIG_ATTRIB(&config
->Base
, EGL_NATIVE_VISUAL_ID
, attribs
.id
);
435 SET_CONFIG_ATTRIB(&config
->Base
, EGL_BUFFER_SIZE
, attribs
.bufferSize
);
436 SET_CONFIG_ATTRIB(&config
->Base
, EGL_RED_SIZE
, attribs
.redSize
);
437 SET_CONFIG_ATTRIB(&config
->Base
, EGL_GREEN_SIZE
, attribs
.greenSize
);
438 SET_CONFIG_ATTRIB(&config
->Base
, EGL_BLUE_SIZE
, attribs
.blueSize
);
439 SET_CONFIG_ATTRIB(&config
->Base
, EGL_ALPHA_SIZE
, attribs
.alphaSize
);
440 SET_CONFIG_ATTRIB(&config
->Base
, EGL_DEPTH_SIZE
, attribs
.depthSize
);
441 SET_CONFIG_ATTRIB(&config
->Base
, EGL_STENCIL_SIZE
, attribs
.stencilSize
);
442 SET_CONFIG_ATTRIB(&config
->Base
, EGL_SAMPLES
, attribs
.numSamples
);
443 SET_CONFIG_ATTRIB(&config
->Base
, EGL_SAMPLE_BUFFERS
, attribs
.numMultisample
);
444 SET_CONFIG_ATTRIB(&config
->Base
, EGL_CONFORMANT
, all_apis
);
445 SET_CONFIG_ATTRIB(&config
->Base
, EGL_RENDERABLE_TYPE
, all_apis
);
446 SET_CONFIG_ATTRIB(&config
->Base
, EGL_SURFACE_TYPE
,
447 (EGL_WINDOW_BIT
/*| EGL_PBUFFER_BIT | EGL_PIXMAP_BIT*/));
449 /* XXX possibly other things to init... */
451 _eglAddConfig(disp
, &config
->Base
);
459 * Called via eglInitialize(), GLX_drv->API.Initialize().
462 GLX_eglInitialize(_EGLDriver
*drv
, _EGLDisplay
*disp
,
463 EGLint
*major
, EGLint
*minor
)
465 struct GLX_egl_display
*GLX_dpy
;
467 GLX_dpy
= CALLOC_STRUCT(GLX_egl_display
);
469 return _eglError(EGL_BAD_ALLOC
, "eglInitialize");
471 GLX_dpy
->dpy
= (Display
*) disp
->NativeDisplay
;
473 GLX_dpy
->dpy
= XOpenDisplay(NULL
);
475 _eglLog(_EGL_WARNING
, "GLX: XOpenDisplay failed");
481 disp
->DriverData
= (void *) GLX_dpy
;
482 disp
->ClientAPIsMask
= all_apis
;
484 glXQueryVersion(GLX_dpy
->dpy
, &GLX_dpy
->glx_maj
, &GLX_dpy
->glx_min
);
486 /* we're supporting EGL 1.4 */
490 create_configs(disp
, GLX_dpy
);
496 * Called via eglTerminate(), drv->API.Terminate().
499 GLX_eglTerminate(_EGLDriver
*drv
, _EGLDisplay
*disp
)
501 struct GLX_egl_display
*GLX_dpy
= GLX_egl_display(disp
);
503 _eglReleaseDisplayResources(drv
, disp
);
504 _eglCleanupDisplay(disp
);
506 if (GLX_dpy
->visuals
)
507 XFree(GLX_dpy
->visuals
);
508 if (GLX_dpy
->fbconfigs
)
509 XFree(GLX_dpy
->fbconfigs
);
511 if (!disp
->NativeDisplay
)
512 XCloseDisplay(GLX_dpy
->dpy
);
515 disp
->DriverData
= NULL
;
522 * Called via eglCreateContext(), drv->API.CreateContext().
525 GLX_eglCreateContext(_EGLDriver
*drv
, _EGLDisplay
*disp
, _EGLConfig
*conf
,
526 _EGLContext
*share_list
, const EGLint
*attrib_list
)
528 struct GLX_egl_context
*GLX_ctx
= CALLOC_STRUCT(GLX_egl_context
);
529 struct GLX_egl_display
*GLX_dpy
= GLX_egl_display(disp
);
530 struct GLX_egl_context
*GLX_ctx_shared
= GLX_egl_context(share_list
);
533 _eglError(EGL_BAD_ALLOC
, "eglCreateContext");
537 if (!_eglInitContext(drv
, &GLX_ctx
->Base
, conf
, attrib_list
)) {
542 #ifdef GLX_VERSION_1_3
543 if (GLX_dpy
->fbconfigs
)
545 glXCreateNewContext(GLX_dpy
->dpy
,
546 GLX_dpy
->fbconfigs
[GLX_egl_config_index(conf
)],
548 GLX_ctx_shared
? GLX_ctx_shared
->context
: NULL
,
553 glXCreateContext(GLX_dpy
->dpy
,
554 &GLX_dpy
->visuals
[GLX_egl_config_index(conf
)],
555 GLX_ctx_shared
? GLX_ctx_shared
->context
: NULL
,
557 if (!GLX_ctx
->context
) {
563 /* (maybe?) need to have a direct rendering context */
564 if (!glXIsDirect(GLX_dpy
->dpy
, GLX_ctx
->context
)) {
565 glXDestroyContext(GLX_dpy
->dpy
, GLX_ctx
->context
);
571 return &GLX_ctx
->Base
;
576 * Called via eglMakeCurrent(), drv->API.MakeCurrent().
579 GLX_eglMakeCurrent(_EGLDriver
*drv
, _EGLDisplay
*disp
, _EGLSurface
*dsurf
,
580 _EGLSurface
*rsurf
, _EGLContext
*ctx
)
582 struct GLX_egl_display
*GLX_dpy
= GLX_egl_display(disp
);
583 struct GLX_egl_surface
*GLX_dsurf
= GLX_egl_surface(dsurf
);
584 struct GLX_egl_surface
*GLX_rsurf
= GLX_egl_surface(rsurf
);
585 struct GLX_egl_context
*GLX_ctx
= GLX_egl_context(ctx
);
586 GLXDrawable ddraw
, rdraw
;
589 if (!_eglMakeCurrent(drv
, disp
, dsurf
, rsurf
, ctx
))
592 ddraw
= (GLX_dsurf
) ? GLX_dsurf
->drawable
: None
;
593 rdraw
= (GLX_rsurf
) ? GLX_rsurf
->drawable
: None
;
594 cctx
= (GLX_ctx
) ? GLX_ctx
->context
: NULL
;
596 #ifdef GLX_VERSION_1_3
597 if (glXMakeContextCurrent(GLX_dpy
->dpy
, ddraw
, rdraw
, cctx
))
601 if (ddraw
== rdraw
&& glXMakeCurrent(GLX_dpy
->dpy
, ddraw
, cctx
))
607 /** Get size of given window */
609 get_drawable_size(Display
*dpy
, Drawable d
, uint
*width
, uint
*height
)
614 unsigned int w
, h
, bw
, depth
;
615 stat
= XGetGeometry(dpy
, d
, &root
, &xpos
, &ypos
, &w
, &h
, &bw
, &depth
);
622 * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
625 GLX_eglCreateWindowSurface(_EGLDriver
*drv
, _EGLDisplay
*disp
, _EGLConfig
*conf
,
626 NativeWindowType window
, const EGLint
*attrib_list
)
628 struct GLX_egl_display
*GLX_dpy
= GLX_egl_display(disp
);
629 struct GLX_egl_surface
*GLX_surf
;
632 GLX_surf
= CALLOC_STRUCT(GLX_egl_surface
);
634 _eglError(EGL_BAD_ALLOC
, "eglCreateWindowSurface");
638 if (!_eglInitSurface(drv
, &GLX_surf
->Base
, EGL_WINDOW_BIT
,
639 conf
, attrib_list
)) {
644 GLX_surf
->drawable
= window
;
645 get_drawable_size(GLX_dpy
->dpy
, window
, &width
, &height
);
646 GLX_surf
->Base
.Width
= width
;
647 GLX_surf
->Base
.Height
= height
;
649 return &GLX_surf
->Base
;
652 #ifdef GLX_VERSION_1_3
654 GLX_eglCreatePixmapSurface(_EGLDriver
*drv
, _EGLDisplay
*disp
, _EGLConfig
*conf
,
655 NativePixmapType pixmap
, const EGLint
*attrib_list
)
657 struct GLX_egl_display
*GLX_dpy
= GLX_egl_display(disp
);
658 struct GLX_egl_surface
*GLX_surf
;
661 /* GLX must >= 1.3 */
662 if (!(GLX_dpy
->glx_maj
== 1 && GLX_dpy
->glx_min
>= 3))
665 GLX_surf
= CALLOC_STRUCT(GLX_egl_surface
);
667 _eglError(EGL_BAD_ALLOC
, "eglCreatePixmapSurface");
671 if (!_eglInitSurface(drv
, &GLX_surf
->Base
, EGL_PIXMAP_BIT
,
672 conf
, attrib_list
)) {
677 for (i
= 0; attrib_list
&& attrib_list
[i
] != EGL_NONE
; i
++) {
678 switch (attrib_list
[i
]) {
679 /* no attribs at this time */
681 _eglError(EGL_BAD_ATTRIBUTE
, "eglCreatePixmapSurface");
688 glXCreatePixmap(GLX_dpy
->dpy
,
689 GLX_dpy
->fbconfigs
[GLX_egl_config_index(conf
)],
691 if (!GLX_surf
->drawable
) {
696 return &GLX_surf
->Base
;
700 GLX_eglCreatePbufferSurface(_EGLDriver
*drv
, _EGLDisplay
*disp
,
701 _EGLConfig
*conf
, const EGLint
*attrib_list
)
703 struct GLX_egl_display
*GLX_dpy
= GLX_egl_display(disp
);
704 struct GLX_egl_surface
*GLX_surf
;
708 /* GLX must >= 1.3 */
709 if (!(GLX_dpy
->glx_maj
== 1 && GLX_dpy
->glx_min
>= 3))
712 GLX_surf
= CALLOC_STRUCT(GLX_egl_surface
);
714 _eglError(EGL_BAD_ALLOC
, "eglCreatePbufferSurface");
718 if (!_eglInitSurface(drv
, &GLX_surf
->Base
, EGL_PBUFFER_BIT
,
719 conf
, attrib_list
)) {
724 while(attrib_list
[i
] != EGL_NONE
) {
725 switch (attrib_list
[i
]) {
727 attribs
[j
++] = GLX_PBUFFER_WIDTH
;
728 attribs
[j
++] = attrib_list
[i
+1];
731 attribs
[j
++] = GLX_PBUFFER_HEIGHT
;
732 attribs
[j
++] = attrib_list
[i
+1];
740 glXCreatePbuffer(GLX_dpy
->dpy
,
741 GLX_dpy
->fbconfigs
[GLX_egl_config_index(conf
)],
743 if (!GLX_surf
->drawable
) {
748 return &GLX_surf
->Base
;
753 GLX_eglDestroySurface(_EGLDriver
*drv
, _EGLDisplay
*disp
, _EGLSurface
*surf
)
755 struct GLX_egl_display
*GLX_dpy
= GLX_egl_display(disp
);
756 if (!_eglIsSurfaceBound(surf
)) {
757 struct GLX_egl_surface
*GLX_surf
= GLX_egl_surface(surf
);
758 switch (surf
->Type
) {
759 case EGL_PBUFFER_BIT
:
760 glXDestroyPbuffer(GLX_dpy
->dpy
, GLX_surf
->drawable
);
763 glXDestroyPixmap(GLX_dpy
->dpy
, GLX_surf
->drawable
);
776 GLX_eglBindTexImage(_EGLDriver
*drv
, _EGLDisplay
*disp
, _EGLSurface
*surf
,
779 struct GLX_egl_display
*GLX_dpy
= GLX_egl_display(disp
);
780 struct GLX_egl_surface
*GLX_surf
= GLX_egl_surface(surf
);
783 glXBindTexImageEXT(GLX_dpy
->dpy
, GLX_surf
->drawable
,
784 GLX_FRONT_LEFT_EXT
, NULL
);
791 GLX_eglReleaseTexImage(_EGLDriver
*drv
, _EGLDisplay
*disp
, _EGLSurface
*surf
,
794 struct GLX_egl_display
*GLX_dpy
= GLX_egl_display(disp
);
795 struct GLX_egl_surface
*GLX_surf
= GLX_egl_surface(surf
);
798 glXReleaseTexImageEXT(GLX_dpy
->dpy
, GLX_surf
->drawable
,
806 GLX_eglSwapBuffers(_EGLDriver
*drv
, _EGLDisplay
*disp
, _EGLSurface
*draw
)
808 struct GLX_egl_display
*GLX_dpy
= GLX_egl_display(disp
);
809 struct GLX_egl_surface
*GLX_surf
= GLX_egl_surface(draw
);
811 _eglLog(_EGL_DEBUG
, "GLX: EGL SwapBuffers 0x%x",draw
);
813 glXSwapBuffers(GLX_dpy
->dpy
, GLX_surf
->drawable
);
819 * Called from eglGetProcAddress() via drv->API.GetProcAddress().
822 GLX_eglGetProcAddress(const char *procname
)
824 /* This is a bit of a hack to get at the gallium/Mesa state tracker
825 * function st_get_proc_address(). This will probably change at
828 _EGLProc (*get_proc_addr
)(const char *procname
);
830 get_proc_addr
= dlsym(NULL
, "st_get_proc_address");
832 return get_proc_addr(procname
);
834 proc_addr
= glXGetProcAddress((const GLubyte
*)procname
);
838 return (_EGLProc
)dlsym(NULL
, procname
);
843 GLX_Unload(_EGLDriver
*drv
)
845 struct GLX_egl_driver
*GLX_drv
= GLX_egl_driver(drv
);
851 * This is the main entrypoint into the driver, called by libEGL.
852 * Create a new _EGLDriver object and init its dispatch table.
855 _eglMain(const char *args
)
857 struct GLX_egl_driver
*GLX_drv
= CALLOC_STRUCT(GLX_egl_driver
);
862 _eglInitDriverFallbacks(&GLX_drv
->Base
);
863 GLX_drv
->Base
.API
.Initialize
= GLX_eglInitialize
;
864 GLX_drv
->Base
.API
.Terminate
= GLX_eglTerminate
;
865 GLX_drv
->Base
.API
.CreateContext
= GLX_eglCreateContext
;
866 GLX_drv
->Base
.API
.MakeCurrent
= GLX_eglMakeCurrent
;
867 GLX_drv
->Base
.API
.CreateWindowSurface
= GLX_eglCreateWindowSurface
;
868 #ifdef GLX_VERSION_1_3
869 GLX_drv
->Base
.API
.CreatePixmapSurface
= GLX_eglCreatePixmapSurface
;
870 GLX_drv
->Base
.API
.CreatePbufferSurface
= GLX_eglCreatePbufferSurface
;
872 GLX_drv
->Base
.API
.DestroySurface
= GLX_eglDestroySurface
;
873 GLX_drv
->Base
.API
.BindTexImage
= GLX_eglBindTexImage
;
874 GLX_drv
->Base
.API
.ReleaseTexImage
= GLX_eglReleaseTexImage
;
875 GLX_drv
->Base
.API
.SwapBuffers
= GLX_eglSwapBuffers
;
876 GLX_drv
->Base
.API
.GetProcAddress
= GLX_eglGetProcAddress
;
878 GLX_drv
->Base
.Name
= "GLX";
879 GLX_drv
->Base
.Unload
= GLX_Unload
;
881 return &GLX_drv
->Base
;