#include <X11/Xlibint.h>
#include <X11/extensions/Xext.h>
#include <X11/extensions/extutil.h>
+#include <X11/extensions/Xfixes.h>
+#include <X11/extensions/Xdamage.h>
#include "glheader.h"
#include "glxclient.h"
#include "xf86dri.h"
#include "sarea.h"
#include <stdio.h>
#include <dlfcn.h>
-#include "dri_glx.h"
#include <sys/types.h>
#include <stdarg.h>
#include "glcontextmodes.h"
#define RTLD_GLOBAL 0
#endif
+typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate;
+typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate;
+
+struct __GLXDRIdisplayPrivateRec {
+ __GLXDRIdisplay base;
+
+ /*
+ ** XFree86-DRI version information
+ */
+ int driMajor;
+ int driMinor;
+ int driPatch;
+};
+
+struct __GLXDRIcontextPrivateRec {
+ __GLXDRIcontext base;
+ __DRIcontext driContext;
+ XID hwContextID;
+};
#ifndef DEFAULT_DRIVER_DIR
/* this is normally defined in Mesa/configs/default with DRI_DRIVER_SEARCH_PATH */
/* Attempt to make sure libGL symbols will be visible to the driver */
glhandle = dlopen("libGL.so.1", RTLD_NOW | RTLD_GLOBAL);
- libPaths = DEFAULT_DRIVER_DIR;
+ libPaths = NULL;
if (geteuid() == getuid()) {
/* don't allow setuid apps to use LIBGL_DRIVERS_PATH */
libPaths = getenv("LIBGL_DRIVERS_PATH");
if (!libPaths)
libPaths = getenv("LIBGL_DRIVERS_DIR"); /* deprecated */
}
+ if (libPaths == NULL)
+ libPaths = DEFAULT_DRIVER_DIR;
handle = NULL;
for (p = libPaths; *p; p = next) {
XserverRegion region;
int i;
int x_off, y_off;
- __GLXdrawable *glxDraw =
- containerOf(driDraw, __GLXdrawable, driDrawable);
+ __GLXDRIdrawable *glxDraw =
+ containerOf(driDraw, __GLXDRIdrawable, driDrawable);
__GLXscreenConfigs *psc = glxDraw->psc;
Display *dpy = psc->dpy;
Drawable drawable;
int *backX, int *backY,
int *numBackClipRects, drm_clip_rect_t **pBackClipRects)
{
- __GLXdrawable *glxDraw =
- containerOf(drawable, __GLXdrawable, driDrawable);
+ __GLXDRIdrawable *glxDraw =
+ containerOf(drawable, __GLXDRIdrawable, driDrawable);
__GLXscreenConfigs *psc = glxDraw->psc;
Display *dpy = psc->dpy;
*/
static void *
CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
- __DRIdisplay * driDpy,
+ __GLXDRIdisplayPrivate * driDpy,
PFNCREATENEWSCREENFUNC createNewScreen)
{
- __DRIscreenPrivate *psp = NULL;
+ void *psp = NULL;
#ifndef GLX_USE_APPLEGL
drm_handle_t hSAREA;
drmAddress pSAREA = MAP_FAILED;
const char * err_msg;
const char * err_extra;
- dri_version.major = driDpy->private->driMajor;
- dri_version.minor = driDpy->private->driMinor;
- dri_version.patch = driDpy->private->driPatch;
+ dri_version.major = driDpy->driMajor;
+ dri_version.minor = driDpy->driMinor;
+ dri_version.patch = driDpy->driPatch;
err_msg = "XF86DRIOpenConnection";
err_msg = "InitDriver";
err_extra = NULL;
psp = (*createNewScreen)(scrn,
- &psc->driScreen,
+ &psc->__driScreen,
& ddx_version,
& dri_version,
& drm_version,
return psp;
}
-void
-driCreateScreen(__GLXscreenConfigs *psc, int screen,
- __GLXdisplayPrivate *priv)
+static void driDestroyContext(__GLXDRIcontext *context,
+ __GLXscreenConfigs *psc, Display *dpy)
{
- PFNCREATENEWSCREENFUNC createNewScreen;
+ __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
+
+ (*pcp->driContext.destroyContext)(&pcp->driContext);
- if (priv->driDisplay.private == NULL)
- return;
+ XF86DRIDestroyContext(psc->dpy, psc->scr, pcp->hwContextID);
+}
- /* Create drawable hash */
- psc->drawHash = __glxHashCreate();
- if ( psc->drawHash == NULL )
- return;
+static Bool driBindContext(__GLXDRIcontext *context,
+ __GLXDRIdrawable *draw, __GLXDRIdrawable *read)
+{
+ __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
+
+ return (*pcp->driContext.bindContext)(&pcp->driContext,
+ &draw->driDrawable,
+ &read->driDrawable);
+}
+
+static void driUnbindContext(__GLXDRIcontext *context)
+{
+ __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
+
+ (*pcp->driContext.unbindContext)(&pcp->driContext);
+}
+
+static __GLXDRIcontext *driCreateContext(__GLXscreenConfigs *psc,
+ const __GLcontextModes *mode,
+ GLXContext gc,
+ GLXContext shareList, int renderType)
+{
+ __GLXDRIcontextPrivate *pcp, *pcp_shared;
+ drm_context_t hwContext;
+ __DRIcontext *shared = NULL;
+
+ if (psc && psc->driScreen) {
+ if (shareList) {
+ pcp_shared = (__GLXDRIcontextPrivate *) shareList->driContext;
+ shared = &pcp_shared->driContext;
+ }
+
+ pcp = Xmalloc(sizeof *pcp);
+ if (pcp == NULL)
+ return NULL;
+
+ if (!XF86DRICreateContextWithConfig(psc->dpy, psc->scr,
+ mode->visualID,
+ &pcp->hwContextID, &hwContext)) {
+ Xfree(pcp);
+ return NULL;
+ }
+
+ pcp->driContext.private =
+ (*psc->__driScreen.createNewContext)(&psc->__driScreen,
+ mode, renderType,
+ shared,
+ hwContext,
+ &pcp->driContext);
+ if (pcp->driContext.private == NULL) {
+ XF86DRIDestroyContext(psc->dpy, psc->scr, pcp->hwContextID);
+ Xfree(pcp);
+ return NULL;
+ }
+
+ pcp->base.destroyContext = driDestroyContext;
+ pcp->base.bindContext = driBindContext;
+ pcp->base.unbindContext = driUnbindContext;
+
+ return &pcp->base;
+ }
+
+ return NULL;
+}
+
+static void driDestroyDrawable(__GLXDRIdrawable *pdraw)
+{
+ __GLXscreenConfigs *psc = pdraw->psc;
+
+ (*pdraw->driDrawable.destroyDrawable)(&pdraw->driDrawable);
+ XF86DRIDestroyDrawable(psc->dpy, psc->scr, pdraw->drawable);
+ Xfree(pdraw);
+}
+
+static __GLXDRIdrawable *driCreateDrawable(__GLXscreenConfigs *psc,
+ GLXDrawable drawable,
+ GLXContext gc)
+{
+ __GLXDRIdrawable *pdraw;
+ drm_drawable_t hwDrawable;
+ void *empty_attribute_list = NULL;
+
+ pdraw = Xmalloc(sizeof(*pdraw));
+ if (!pdraw)
+ return NULL;
+
+ pdraw->drawable = drawable;
+ pdraw->psc = psc;
+
+ if (!XF86DRICreateDrawable(psc->dpy, psc->scr, drawable, &hwDrawable))
+ return NULL;
+
+ /* Create a new drawable */
+ pdraw->driDrawable.private =
+ (*psc->__driScreen.createNewDrawable)(&psc->__driScreen,
+ gc->mode,
+ &pdraw->driDrawable,
+ hwDrawable,
+ GLX_WINDOW_BIT,
+ 0,
+ empty_attribute_list);
+
+ if (!pdraw->driDrawable.private) {
+ XF86DRIDestroyDrawable(psc->dpy, psc->scr, drawable);
+ Xfree(pdraw);
+ return NULL;
+ }
+
+ pdraw->destroyDrawable = driDestroyDrawable;
+
+ return pdraw;
+}
+
+static void driDestroyScreen(__GLXscreenConfigs *psc)
+{
+ /* Free the direct rendering per screen data */
+ if (psc->__driScreen.private)
+ (*psc->__driScreen.destroyScreen)(&psc->__driScreen);
+ psc->__driScreen.private = NULL;
+ if (psc->driver)
+ dlclose(psc->driver);
+}
+
+static __GLXDRIscreen *driCreateScreen(__GLXscreenConfigs *psc, int screen,
+ __GLXdisplayPrivate *priv)
+{
+ PFNCREATENEWSCREENFUNC createNewScreen;
+ __GLXDRIdisplayPrivate *pdp;
+ __GLXDRIscreen *psp;
+
+ psp = Xmalloc(sizeof *psp);
+ if (psp == NULL)
+ return NULL;
/* Initialize per screen dynamic client GLX extensions */
psc->ext_list_first_time = GL_TRUE;
psc->driver = driGetDriver(priv->dpy, screen);
createNewScreen = dlsym(psc->driver, createNewScreenName);
if (createNewScreenName == NULL)
- return;
+ return NULL;
- psc->driScreen.private =
- CallCreateNewScreen(psc->dpy, screen, psc,
- &priv->driDisplay, createNewScreen);
- if (psc->driScreen.private != NULL)
+ pdp = (__GLXDRIdisplayPrivate *) priv->driDisplay;
+ psc->__driScreen.private =
+ CallCreateNewScreen(psc->dpy, screen, psc, pdp, createNewScreen);
+ if (psc->__driScreen.private != NULL)
__glXScrEnableDRIExtension(psc);
-}
-void driDestroyScreen(__GLXscreenConfigs *psc)
-{
- /* Free the direct rendering per screen data */
- if (psc->driScreen.private)
- (*psc->driScreen.destroyScreen)(&psc->driScreen);
- psc->driScreen.private = NULL;
- if (psc->drawHash)
- __glxHashDestroy(psc->drawHash);
- if (psc->driver)
- dlclose(psc->driver);
+ psp->destroyScreen = driDestroyScreen;
+ psp->createContext = driCreateContext;
+ psp->createDrawable = driCreateDrawable;
+
+ return psp;
}
/* Called from __glXFreeDisplayPrivate.
*/
-static void driDestroyDisplay(Display *dpy, void *private)
+static void driDestroyDisplay(__GLXDRIdisplay *dpy)
{
- __DRIdisplayPrivate *pdpyp = (__DRIdisplayPrivate *)private;
-
- if (pdpyp)
- Xfree(pdpyp);
+ Xfree(dpy);
}
-
/*
* Allocate, initialize and return a __DRIdisplayPrivate object.
* This is called from __glXInitialize() when we are given a new
* display pointer.
*/
-void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp)
+_X_HIDDEN __GLXDRIdisplay *driCreateDisplay(Display *dpy)
{
- __DRIdisplayPrivate *pdpyp;
+ __GLXDRIdisplayPrivate *pdpyp;
int eventBase, errorBase;
int major, minor, patch;
- /* Initialize these fields to NULL in case we fail.
- * If we don't do this we may later get segfaults trying to free random
- * addresses when the display is closed.
- */
- pdisp->private = NULL;
- pdisp->destroyDisplay = NULL;
-
if (!XF86DRIQueryExtension(dpy, &eventBase, &errorBase)) {
return NULL;
}
return NULL;
}
- pdpyp = (__DRIdisplayPrivate *)Xmalloc(sizeof(__DRIdisplayPrivate));
+ pdpyp = Xmalloc(sizeof *pdpyp);
if (!pdpyp) {
return NULL;
}
pdpyp->driMinor = minor;
pdpyp->driPatch = patch;
- pdisp->destroyDisplay = driDestroyDisplay;
+ pdpyp->base.destroyDisplay = driDestroyDisplay;
+ pdpyp->base.createScreen = driCreateScreen;
- return (void *)pdpyp;
+ return &pdpyp->base;
}
#endif /* GLX_DIRECT_RENDERING */