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 * Code to interface a DRI driver to libEGL.
31 * Note that unlike previous DRI/EGL interfaces, this one is meant to
32 * be used _with_ X. Applications will use eglCreateWindowSurface()
33 * to render into X-created windows.
35 * This is an EGL driver that, in turn, loads a regular DRI driver.
36 * There are some dependencies on code in libGL, but those coudl be
37 * removed with some effort.
45 #include <sys/types.h>
52 #include "glxclient.h"
54 #include "drm_sarea.h"
56 #define _EGL_PLATFORM_X
58 #include "eglconfig.h"
59 #include "eglcontext.h"
60 #include "egldisplay.h"
61 #include "egldriver.h"
62 #include "eglglobals.h"
65 #include "eglsurface.h"
69 #define CALLOC_STRUCT(T) (struct T *) calloc(1, sizeof(struct T))
72 /** subclass of _EGLDriver */
73 struct xdri_egl_driver
75 _EGLDriver Base
; /**< base class */
77 const char *dri_driver_name
; /**< name of DRI driver to load */
78 void *dri_driver_handle
; /**< returned by dlopen(dri_driver_name) */
84 __DRIscreen driScreen
;
85 __DRIframebuffer framebuffer
;
93 /** subclass of _EGLContext */
94 struct xdri_egl_context
96 _EGLContext Base
; /**< base class */
98 __DRIcontext driContext
;
102 /** subclass of _EGLSurface */
103 struct xdri_egl_surface
105 _EGLSurface Base
; /**< base class */
107 __DRIid driDrawable
; /**< DRI surface */
108 drm_drawable_t hDrawable
;
112 /** subclass of _EGLConfig */
113 struct xdri_egl_config
115 _EGLConfig Base
; /**< base class */
117 const __GLcontextModes
*mode
; /**< corresponding GLX mode */
122 static struct xdri_egl_driver
*TheDriver
= NULL
;
126 static struct xdri_egl_driver
*
127 xdri_egl_driver(_EGLDriver
*drv
)
129 return (struct xdri_egl_driver
*) drv
;
133 /** Map EGLSurface handle to xdri_egl_surface object */
134 static struct xdri_egl_surface
*
135 lookup_surface(EGLSurface surf
)
137 _EGLSurface
*surface
= _eglLookupSurface(surf
);
138 return (struct xdri_egl_surface
*) surface
;
142 /** Map EGLContext handle to xdri_egl_context object */
143 static struct xdri_egl_context
*
144 lookup_context(EGLContext c
)
146 _EGLContext
*context
= _eglLookupContext(c
);
147 return (struct xdri_egl_context
*) context
;
151 /** Map EGLConfig handle to xdri_egl_config object */
152 static struct xdri_egl_config
*
153 lookup_config(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
)
155 _EGLConfig
*conf
= _eglLookupConfig(drv
, dpy
, config
);
156 return (struct xdri_egl_config
*) conf
;
161 /** Get size of given window */
163 get_drawable_size(Display
*dpy
, Drawable d
, uint
*width
, uint
*height
)
168 unsigned int w
, h
, bw
, depth
;
169 stat
= XGetGeometry(dpy
, d
, &root
, &xpos
, &ypos
, &w
, &h
, &bw
, &depth
);
177 * Produce a set of EGL configs.
178 * Note that we get the list of GLcontextModes from the GLX library.
179 * This dependency on GLX lib will be removed someday.
182 create_configs(_EGLDisplay
*disp
)
184 const __GLcontextModes
*m
;
185 __GLXdisplayPrivate
*priv
= __glXInitialize(disp
->Xdpy
);
186 __GLXscreenConfigs
*scrn
= priv
->screenConfigs
;
189 for (m
= scrn
->configs
; m
; m
= m
->next
) {
190 /* EGL requires double-buffered configs */
191 if (m
->doubleBufferMode
) {
192 struct xdri_egl_config
*config
= CALLOC_STRUCT(xdri_egl_config
);
194 _eglInitConfig(&config
->Base
, id
++);
196 SET_CONFIG_ATTRIB(&config
->Base
, EGL_BUFFER_SIZE
, m
->rgbBits
);
197 SET_CONFIG_ATTRIB(&config
->Base
, EGL_RED_SIZE
, m
->redBits
);
198 SET_CONFIG_ATTRIB(&config
->Base
, EGL_GREEN_SIZE
, m
->greenBits
);
199 SET_CONFIG_ATTRIB(&config
->Base
, EGL_BLUE_SIZE
, m
->blueBits
);
200 SET_CONFIG_ATTRIB(&config
->Base
, EGL_ALPHA_SIZE
, m
->alphaBits
);
201 SET_CONFIG_ATTRIB(&config
->Base
, EGL_DEPTH_SIZE
, m
->depthBits
);
202 SET_CONFIG_ATTRIB(&config
->Base
, EGL_STENCIL_SIZE
, m
->stencilBits
);
203 SET_CONFIG_ATTRIB(&config
->Base
, EGL_NATIVE_VISUAL_ID
, m
->visualID
);
204 SET_CONFIG_ATTRIB(&config
->Base
, EGL_NATIVE_VISUAL_TYPE
, m
->visualType
);
205 /* XXX only window rendering allowed ATM */
206 SET_CONFIG_ATTRIB(&config
->Base
, EGL_SURFACE_TYPE
, EGL_WINDOW_BIT
);
208 /* XXX possibly other things to init... */
210 /* Ptr from EGL config to GLcontextMode. Used in CreateContext(). */
213 _eglAddConfig(disp
, &config
->Base
);
220 * Called via __DRIinterfaceMethods object
223 dri_get_proc_address(const char * proc_name
)
230 dri_context_modes_destroy(__GLcontextModes
*modes
)
232 _eglLog(_EGL_DEBUG
, "%s", __FUNCTION__
);
235 __GLcontextModes
* const next
= modes
->next
;
243 * Create a linked list of 'count' GLcontextModes.
244 * These are used during the client/server visual negotiation phase,
247 static __GLcontextModes
*
248 dri_context_modes_create(unsigned count
, size_t minimum_size
)
250 /* This code copied from libGLX, and modified */
251 const size_t size
= (minimum_size
> sizeof(__GLcontextModes
))
252 ? minimum_size
: sizeof(__GLcontextModes
);
253 __GLcontextModes
* head
= NULL
;
254 __GLcontextModes
** next
;
258 for (i
= 0 ; i
< count
; i
++) {
259 *next
= (__GLcontextModes
*) calloc(1, size
);
261 dri_context_modes_destroy(head
);
266 (*next
)->doubleBufferMode
= 1;
267 (*next
)->visualID
= GLX_DONT_CARE
;
268 (*next
)->visualType
= GLX_DONT_CARE
;
269 (*next
)->visualRating
= GLX_NONE
;
270 (*next
)->transparentPixel
= GLX_NONE
;
271 (*next
)->transparentRed
= GLX_DONT_CARE
;
272 (*next
)->transparentGreen
= GLX_DONT_CARE
;
273 (*next
)->transparentBlue
= GLX_DONT_CARE
;
274 (*next
)->transparentAlpha
= GLX_DONT_CARE
;
275 (*next
)->transparentIndex
= GLX_DONT_CARE
;
276 (*next
)->xRenderable
= GLX_DONT_CARE
;
277 (*next
)->fbconfigID
= GLX_DONT_CARE
;
278 (*next
)->swapMethod
= GLX_SWAP_UNDEFINED_OML
;
279 (*next
)->bindToTextureRgb
= GLX_DONT_CARE
;
280 (*next
)->bindToTextureRgba
= GLX_DONT_CARE
;
281 (*next
)->bindToMipmapTexture
= GLX_DONT_CARE
;
282 (*next
)->bindToTextureTargets
= 0;
283 (*next
)->yInverted
= GLX_DONT_CARE
;
285 next
= & ((*next
)->next
);
293 dri_find_dri_screen(__DRInativeDisplay
*ndpy
, int scrn
)
297 return &TheDriver
->driScreen
;
302 dri_window_exists(__DRInativeDisplay
*ndpy
, __DRIid draw
)
309 dri_create_context(__DRInativeDisplay
*ndpy
, int screenNum
, int configID
,
310 void * contextID
, drm_context_t
* hw_context
)
312 assert(configID
>= 0);
313 return XF86DRICreateContextWithConfig(ndpy
, screenNum
,
314 configID
, contextID
, hw_context
);
319 dri_destroy_context(__DRInativeDisplay
* ndpy
, int screen
, __DRIid context
)
321 return XF86DRIDestroyContext(ndpy
, screen
, context
);
326 dri_create_drawable(__DRInativeDisplay
* ndpy
, int screen
,
327 __DRIid drawable
, drm_drawable_t
* hHWDrawable
)
329 _eglLog(_EGL_DEBUG
, "XDRI: %s", __FUNCTION__
);
331 /* Create DRI drawable for given window ID (drawable) */
332 if (!XF86DRICreateDrawable(ndpy
, screen
, drawable
, hHWDrawable
))
340 dri_destroy_drawable(__DRInativeDisplay
* ndpy
, int screen
, __DRIid drawable
)
342 _eglLog(_EGL_DEBUG
, "XDRI: %s", __FUNCTION__
);
343 return XF86DRIDestroyDrawable(ndpy
, screen
, drawable
);
348 dri_get_drawable_info(__DRInativeDisplay
*ndpy
, int scrn
,
349 __DRIid draw
, unsigned int * index
, unsigned int * stamp
,
350 int * x
, int * y
, int * width
, int * height
,
351 int * numClipRects
, drm_clip_rect_t
** pClipRects
,
352 int * backX
, int * backY
,
353 int * numBackClipRects
,
354 drm_clip_rect_t
** pBackClipRects
)
356 _eglLog(_EGL_DEBUG
, "XDRI: %s", __FUNCTION__
);
358 if (!XF86DRIGetDrawableInfo(ndpy
, scrn
, draw
, index
, stamp
,
360 numClipRects
, pClipRects
,
362 numBackClipRects
, pBackClipRects
)) {
371 * Table of functions exported by the loader to the driver.
373 static const __DRIinterfaceMethods interface_methods
= {
374 dri_get_proc_address
,
376 dri_context_modes_create
,
377 dri_context_modes_destroy
,
386 dri_destroy_drawable
,
387 dri_get_drawable_info
,
389 NULL
,/*__eglGetUST,*/
390 NULL
,/*__eglGetMSCRate,*/
396 init_drm(struct xdri_egl_driver
*xdri_drv
, _EGLDisplay
*disp
)
398 static const char createNewScreenName
[] = "__driCreateNewScreen_20050727";
399 PFNCREATENEWSCREENFUNC createNewScreen
;
400 int api_ver
= 0;/*__glXGetInternalVersion();*/
401 __DRIversion ddx_version
;
402 __DRIversion dri_version
;
403 __DRIversion drm_version
;
404 drmVersionPtr version
;
408 __GLcontextModes
*modes
;
409 int scrn
= DefaultScreen(disp
->Xdpy
);
411 createNewScreen
= (PFNCREATENEWSCREENFUNC
)
412 dlsym(xdri_drv
->dri_driver_handle
, createNewScreenName
);
413 if (!createNewScreen
) {
414 _eglLog(_EGL_WARNING
, "XDRI: Couldn't find %s function in the driver.",
415 createNewScreenName
);
419 _eglLog(_EGL_DEBUG
, "XDRI: Found %s", createNewScreenName
);
423 * Get the DRI X extension version.
425 dri_version
.major
= 4;
426 dri_version
.minor
= 0;
427 dri_version
.patch
= 0;
430 if (!XF86DRIOpenConnection(disp
->Xdpy
, scrn
,
431 &xdri_drv
->hSAREA
, &xdri_drv
->busID
)) {
432 _eglLog(_EGL_WARNING
, "XF86DRIOpenConnection failed");
435 xdri_drv
->drmFD
= drmOpenOnce(NULL
, xdri_drv
->busID
, &newlyopened
);
436 if (xdri_drv
->drmFD
< 0) {
437 perror("drmOpenOnce failed: ");
441 _eglLog(_EGL_DEBUG
, "XDRI: drmOpenOnce returned %d", xdri_drv
->drmFD
);
445 if (drmGetMagic(xdri_drv
->drmFD
, &xdri_drv
->magic
)) {
446 perror("drmGetMagic failed: ");
450 version
= drmGetVersion(xdri_drv
->drmFD
);
452 drm_version
.major
= version
->version_major
;
453 drm_version
.minor
= version
->version_minor
;
454 drm_version
.patch
= version
->version_patchlevel
;
455 drmFreeVersion(version
);
456 _eglLog(_EGL_DEBUG
, "XDRI: Got DRM version %d.%d.%d",
462 drm_version
.major
= -1;
463 drm_version
.minor
= -1;
464 drm_version
.patch
= -1;
465 _eglLog(_EGL_WARNING
, "XDRI: drmGetVersion() failed");
469 /* Authenticate w/ server.
471 if (!XF86DRIAuthConnection(disp
->Xdpy
, scrn
, xdri_drv
->magic
)) {
472 _eglLog(_EGL_WARNING
, "XDRI: XF86DRIAuthConnection() failed");
476 _eglLog(_EGL_DEBUG
, "XDRI: XF86DRIAuthConnection() success");
485 * Get device name (like "tdfx") and the ddx version
486 * numbers. We'll check the version in each DRI driver's
487 * "createNewScreen" function.
489 if (!XF86DRIGetClientDriverName(disp
->Xdpy
, scrn
,
494 _eglLog(_EGL_WARNING
, "XDRI: XF86DRIGetClientDriverName failed");
498 _eglLog(_EGL_DEBUG
, "XDRI: XF86DRIGetClientDriverName returned %s", driverName
);
502 /* Get framebuffer info.
506 if (!XF86DRIGetDeviceInfo(disp
->Xdpy
, scrn
,
509 &xdri_drv
->framebuffer
.size
,
510 &xdri_drv
->framebuffer
.stride
,
511 &xdri_drv
->framebuffer
.dev_priv_size
,
512 &xdri_drv
->framebuffer
.dev_priv
)) {
513 _eglLog(_EGL_WARNING
, "XDRI: XF86DRIGetDeviceInfo() failed");
517 _eglLog(_EGL_DEBUG
, "XDRI: XF86DRIGetDeviceInfo() success");
519 xdri_drv
->framebuffer
.width
= DisplayWidth(disp
->Xdpy
, scrn
);
520 xdri_drv
->framebuffer
.height
= DisplayHeight(disp
->Xdpy
, scrn
);
523 /* Map the framebuffer region. (this may not be needed)
525 status
= drmMap(xdri_drv
->drmFD
, hFB
, xdri_drv
->framebuffer
.size
,
526 (drmAddressPtr
) &xdri_drv
->framebuffer
.base
);
528 _eglLog(_EGL_WARNING
, "XDRI: drmMap(framebuffer) failed");
532 _eglLog(_EGL_DEBUG
, "XDRI: drmMap(framebuffer) success");
535 /* Map the SAREA region.
537 status
= drmMap(xdri_drv
->drmFD
, xdri_drv
->hSAREA
, SAREA_MAX
, &xdri_drv
->pSAREA
);
539 _eglLog(_EGL_WARNING
, "XDRI: drmMap(sarea) failed");
543 _eglLog(_EGL_DEBUG
, "XDRI: drmMap(sarea) success");
546 /* Create the DRI screen.
548 xdri_drv
->driScreen
.private = createNewScreen(disp
->Xdpy
,
549 scrn
, /* screen number */
550 &xdri_drv
->driScreen
,
555 &xdri_drv
->framebuffer
,
561 if (!xdri_drv
->driScreen
.private) {
562 _eglLog(_EGL_WARNING
, "XDRI: create new screen failed");
566 _eglLog(_EGL_DEBUG
, "XDRI: create new screen success");
569 create_configs(disp
);
571 /* print modes / debug */
575 for (m
= modes
; m
; m
= m
->next
) {
577 "mode ID 0x%x rgba %d %d %d %d z %d s %d db %d\n",
579 m
->redBits
, m
->greenBits
, m
->blueBits
, m
->alphaBits
,
580 m
->depthBits
, m
->stencilBits
, m
->doubleBufferMode
);
589 * Load the DRI driver named by "xdri_drv->dri_driver_name".
590 * Basically, dlopen() the library to set "xdri_drv->dri_driver_handle".
592 * Later, we'll call dlsym(createNewScreenName) to get a pointer to
593 * the driver's createNewScreen() function which is the bootstrap function.
595 * \return EGL_TRUE for success, EGL_FALSE for failure
598 load_dri_driver(struct xdri_egl_driver
*xdri_drv
)
601 int flags
= RTLD_NOW
;
603 /* try "egl_xxx_dri.so" first */
604 snprintf(filename
, sizeof(filename
), "egl_%s.so", xdri_drv
->dri_driver_name
);
605 _eglLog(_EGL_DEBUG
, "XDRI: dlopen(%s)", filename
);
606 xdri_drv
->dri_driver_handle
= dlopen(filename
, flags
);
607 if (xdri_drv
->dri_driver_handle
) {
608 _eglLog(_EGL_DEBUG
, "XDRI: dlopen(%s) OK", filename
);
612 _eglLog(_EGL_DEBUG
, "XDRI: dlopen(%s) fail (%s)", filename
, dlerror());
615 /* try regular "xxx_dri.so" next */
616 snprintf(filename
, sizeof(filename
), "%s.so", xdri_drv
->dri_driver_name
);
617 _eglLog(_EGL_DEBUG
, "XDRI: dlopen(%s)", filename
);
618 xdri_drv
->dri_driver_handle
= dlopen(filename
, flags
);
619 if (xdri_drv
->dri_driver_handle
) {
620 _eglLog(_EGL_DEBUG
, "XDRI: dlopen(%s) OK", filename
);
624 _eglLog(_EGL_WARNING
, "XDRI Could not open %s (%s)", filename
, dlerror());
630 * Called via eglInitialize(), xdri_drv->API.Initialize().
633 xdri_eglInitialize(_EGLDriver
*drv
, EGLDisplay dpy
,
634 EGLint
*minor
, EGLint
*major
)
636 struct xdri_egl_driver
*xdri_drv
= xdri_egl_driver(drv
);
637 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
638 static char name
[100];
640 _eglLog(_EGL_DEBUG
, "XDRI: eglInitialize");
643 disp
->Xdpy
= XOpenDisplay(NULL
);
645 _eglLog(_EGL_WARNING
, "XDRI: XOpenDisplay failed");
650 /* choose the DRI driver to load */
651 xdri_drv
->dri_driver_name
= _eglChooseDRMDriver(0);
652 if (!load_dri_driver(xdri_drv
))
655 if (!init_drm(xdri_drv
, disp
))
658 xdri_drv
->Base
.Initialized
= EGL_TRUE
;
660 snprintf(name
, sizeof(name
), "X/DRI:%s", xdri_drv
->dri_driver_name
);
661 xdri_drv
->Base
.Name
= name
;
663 /* we're supporting EGL 1.4 */
672 * Called via eglTerminate(), drv->API.Terminate().
675 xdri_eglTerminate(_EGLDriver
*drv
, EGLDisplay dpy
)
677 struct xdri_egl_driver
*xdri_drv
= xdri_egl_driver(drv
);
679 _eglLog(_EGL_DEBUG
, "XDRI: eglTerminate");
681 _eglLog(_EGL_DEBUG
, "XDRI: Closing %s", xdri_drv
->dri_driver_name
);
682 dlclose(xdri_drv
->dri_driver_handle
);
683 xdri_drv
->dri_driver_handle
= NULL
;
685 free((void*) xdri_drv
->dri_driver_name
);
692 * Called from eglGetProcAddress() via drv->API.GetProcAddress().
695 xdri_eglGetProcAddress(const char *procname
)
698 _EGLDriver
*drv
= NULL
;
700 struct xdri_egl_driver
*xdri_drv
= xdri_egl_driver(drv
);
701 /*_EGLDisplay *disp = _eglLookupDisplay(dpy);*/
702 _EGLProc
*proc
= xdri_drv
->driScreen
.getProcAddress(procname
);
705 /* This is a bit of a hack to get at the gallium/Mesa state tracker
706 * function st_get_proc_address(). This will probably change at
709 _EGLProc (*st_get_proc_addr
)(const char *procname
);
710 st_get_proc_addr
= dlsym(NULL
, "st_get_proc_address");
711 if (st_get_proc_addr
) {
712 return st_get_proc_addr(procname
);
722 * Called via eglCreateContext(), drv->API.CreateContext().
725 xdri_eglCreateContext(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
,
726 EGLContext share_list
, const EGLint
*attrib_list
)
728 struct xdri_egl_driver
*xdri_drv
= xdri_egl_driver(drv
);
729 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
730 struct xdri_egl_config
*xdri_config
= lookup_config(drv
, dpy
, config
);
732 int renderType
= GLX_RGBA_BIT
;
734 struct xdri_egl_context
*xdri_ctx
= CALLOC_STRUCT(xdri_egl_context
);
736 return EGL_NO_CONTEXT
;
738 if (!_eglInitContext(drv
, dpy
, &xdri_ctx
->Base
, config
, attrib_list
)) {
740 return EGL_NO_CONTEXT
;
745 xdri_ctx
->driContext
.private =
746 xdri_drv
->driScreen
.createNewContext(disp
->Xdpy
,
747 xdri_config
->mode
, renderType
,
748 shared
, &xdri_ctx
->driContext
);
749 if (!xdri_ctx
->driContext
.private) {
750 _eglLog(_EGL_DEBUG
, "driScreen.createNewContext failed");
752 return EGL_NO_CONTEXT
;
755 xdri_ctx
->driContext
.mode
= xdri_config
->mode
;
757 return _eglGetContextHandle(&xdri_ctx
->Base
);
762 * Called via eglMakeCurrent(), drv->API.MakeCurrent().
765 xdri_eglMakeCurrent(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface d
,
766 EGLSurface r
, EGLContext context
)
768 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
769 struct xdri_egl_context
*xdri_ctx
= lookup_context(context
);
770 struct xdri_egl_surface
*xdri_draw
= lookup_surface(d
);
771 struct xdri_egl_surface
*xdri_read
= lookup_surface(r
);
772 __DRIid draw
= xdri_draw
->driDrawable
;
773 __DRIid read
= xdri_read
->driDrawable
;
774 int scrn
= DefaultScreen(disp
->Xdpy
);
776 if (!_eglMakeCurrent(drv
, dpy
, d
, r
, context
))
780 if (!xdri_ctx
->driContext
.bindContext(disp
->Xdpy
, scrn
, draw
, read
,
781 &xdri_ctx
->driContext
)) {
790 * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
793 xdri_eglCreateWindowSurface(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
,
794 NativeWindowType window
, const EGLint
*attrib_list
)
796 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
797 struct xdri_egl_surface
*xdri_surf
;
798 int scrn
= DefaultScreen(disp
->Xdpy
);
801 xdri_surf
= CALLOC_STRUCT(xdri_egl_surface
);
803 return EGL_NO_SURFACE
;
805 if (!_eglInitSurface(drv
, dpy
, &xdri_surf
->Base
, EGL_WINDOW_BIT
,
806 config
, attrib_list
)) {
811 if (!XF86DRICreateDrawable(disp
->Xdpy
, scrn
, window
, &xdri_surf
->hDrawable
)) {
816 xdri_surf
->driDrawable
= window
;
818 _eglSaveSurface(&xdri_surf
->Base
);
820 get_drawable_size(disp
->Xdpy
, window
, &width
, &height
);
821 xdri_surf
->Base
.Width
= width
;
822 xdri_surf
->Base
.Height
= height
;
825 "XDRI: CreateWindowSurface win 0x%x handle %d hDrawable %d",
826 (int) window
, _eglGetSurfaceHandle(&xdri_surf
->Base
),
827 (int) xdri_surf
->hDrawable
);
829 return _eglGetSurfaceHandle(&xdri_surf
->Base
);
834 xdri_eglDestroySurface(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface surface
)
836 struct xdri_egl_surface
*xdri_surf
= lookup_surface(surface
);
838 _eglHashRemove(_eglGlobal
.Surfaces
, (EGLuint
) surface
);
839 if (xdri_surf
->Base
.IsBound
) {
840 xdri_surf
->Base
.DeletePending
= EGL_TRUE
;
844 st_unreference_framebuffer(&surf->Framebuffer);
851 _eglError(EGL_BAD_SURFACE
, "eglDestroySurface");
858 xdri_eglSwapBuffers(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface draw
)
860 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
862 _eglLog(_EGL_DEBUG
, "XDRI: EGL SwapBuffers");
864 /* error checking step: */
865 if (!_eglSwapBuffers(drv
, dpy
, draw
))
869 struct xdri_egl_surface
*xdri_surf
= lookup_surface(draw
);
870 struct xdri_egl_driver
*xdri_drv
= xdri_egl_driver(drv
);
871 __DRIscreen
*psc
= &xdri_drv
->driScreen
;
872 __DRIdrawable
* const pdraw
= psc
->getDrawable(disp
->Xdpy
,
873 xdri_surf
->driDrawable
,
877 pdraw
->swapBuffers(disp
->Xdpy
, pdraw
->private);
879 _eglLog(_EGL_WARNING
, "pdraw is null in SwapBuffers");
887 * This is the main entrypoint into the driver, called by libEGL.
888 * Create a new _EGLDriver object and init its dispatch table.
891 _eglMain(_EGLDisplay
*disp
, const char *args
)
893 struct xdri_egl_driver
*xdri_drv
= CALLOC_STRUCT(xdri_egl_driver
);
898 TheDriver
= xdri_drv
;
900 _eglInitDriverFallbacks(&xdri_drv
->Base
);
901 xdri_drv
->Base
.API
.Initialize
= xdri_eglInitialize
;
902 xdri_drv
->Base
.API
.Terminate
= xdri_eglTerminate
;
904 xdri_drv
->Base
.API
.GetProcAddress
= xdri_eglGetProcAddress
;
906 xdri_drv
->Base
.API
.CreateContext
= xdri_eglCreateContext
;
907 xdri_drv
->Base
.API
.MakeCurrent
= xdri_eglMakeCurrent
;
908 xdri_drv
->Base
.API
.CreateWindowSurface
= xdri_eglCreateWindowSurface
;
909 xdri_drv
->Base
.API
.DestroySurface
= xdri_eglDestroySurface
;
910 xdri_drv
->Base
.API
.SwapBuffers
= xdri_eglSwapBuffers
;
912 xdri_drv
->Base
.ClientAPIsMask
= (EGL_OPENGL_BIT
|
916 xdri_drv
->Base
.Name
= "X/DRI";
918 _eglLog(_EGL_DEBUG
, "XDRI: main(%s)", args
);
920 return &xdri_drv
->Base
;