egl: Use the link functions to manage resources.
[mesa.git] / src / egl / drivers / glx / egl_glx.c
index 8ba70ba7a60a8d40f39c1641cf3bfce9b49184bc..661b313ae2d06a7e85a9bc313c04c2741de4e553 100644 (file)
@@ -267,15 +267,17 @@ glx_token_to_visual_class(int visual_type)
       return None;
    }
 }
-static GLboolean
+static int
 get_fbconfig_attribs(Display *dpy, GLXFBConfig fbconfig,
                     struct visual_attribs *attribs)
 {
    int visual_type;
+   int fbconfig_id;
 
    memset(attribs, 0, sizeof(struct visual_attribs));
 
-   /* We don't use the GLX_FBCONFIG_ID here */
+   glXGetFBConfigAttrib(dpy, fbconfig, GLX_FBCONFIG_ID, &fbconfig_id);
+
    glXGetFBConfigAttrib(dpy, fbconfig, GLX_VISUAL_ID, &attribs->id);
 
 #if 0
@@ -294,11 +296,11 @@ get_fbconfig_attribs(Display *dpy, GLXFBConfig fbconfig,
    glXGetFBConfigAttrib(dpy, fbconfig, GLX_LEVEL, &attribs->level);
    glXGetFBConfigAttrib(dpy, fbconfig, GLX_RENDER_TYPE, &attribs->render_type);
    if (!(attribs->render_type & GLX_RGBA_BIT))
-      return GL_FALSE;
+      return 0;
 
    glXGetFBConfigAttrib(dpy, fbconfig, GLX_DOUBLEBUFFER, &attribs->doubleBuffer);
    if (!attribs->doubleBuffer)
-      return GL_FALSE;
+      return 0;
 
    glXGetFBConfigAttrib(dpy, fbconfig, GLX_STEREO, &attribs->stereo);
    glXGetFBConfigAttrib(dpy, fbconfig, GLX_AUX_BUFFERS, &attribs->auxBuffers);
@@ -332,7 +334,12 @@ get_fbconfig_attribs(Display *dpy, GLXFBConfig fbconfig,
 
    glXGetFBConfigAttrib(dpy, fbconfig, GLX_CONFIG_CAVEAT, &attribs->visualCaveat);
 
-   return GL_TRUE;
+   if (attribs->id == 0) {
+      attribs->id = fbconfig_id;
+      return EGL_PBUFFER_BIT | EGL_PIXMAP_BIT;
+   }
+
+   return EGL_WINDOW_BIT;
 }
 
 #endif
@@ -344,6 +351,7 @@ create_configs(_EGLDisplay *disp, struct GLX_egl_driver *GLX_drv)
    int numVisuals;
    long mask;
    int i;
+   int egl_configs = 1;
    struct visual_attribs attribs;
 
    GLX_drv->fbconfigs = NULL;
@@ -359,13 +367,15 @@ create_configs(_EGLDisplay *disp, struct GLX_egl_driver *GLX_drv)
 
    for (i = 0; i < numVisuals; i++) {
       struct GLX_egl_config *config;
+      int bit;
 
-      if (!get_fbconfig_attribs(disp->Xdpy, GLX_drv->fbconfigs[i], &attribs))
+      bit = get_fbconfig_attribs(disp->Xdpy, GLX_drv->fbconfigs[i], &attribs);
+      if (!bit)
          continue;
 
       config = CALLOC_STRUCT(GLX_egl_config);
 
-      _eglInitConfig(&config->Base, i+1);
+      _eglInitConfig(&config->Base, (i+1));
       SET_CONFIG_ATTRIB(&config->Base, EGL_NATIVE_VISUAL_ID, attribs.id);
       SET_CONFIG_ATTRIB(&config->Base, EGL_BUFFER_SIZE, attribs.bufferSize);
       SET_CONFIG_ATTRIB(&config->Base, EGL_RED_SIZE, attribs.redSize);
@@ -378,8 +388,7 @@ create_configs(_EGLDisplay *disp, struct GLX_egl_driver *GLX_drv)
       SET_CONFIG_ATTRIB(&config->Base, EGL_SAMPLE_BUFFERS, attribs.numMultisample);
       SET_CONFIG_ATTRIB(&config->Base, EGL_CONFORMANT, all_apis);
       SET_CONFIG_ATTRIB(&config->Base, EGL_RENDERABLE_TYPE, all_apis);
-      SET_CONFIG_ATTRIB(&config->Base, EGL_SURFACE_TYPE,
-                        (EGL_WINDOW_BIT | EGL_PBUFFER_BIT | EGL_PIXMAP_BIT));
+      SET_CONFIG_ATTRIB(&config->Base, EGL_SURFACE_TYPE, bit);
 
       /* XXX possibly other things to init... */
 
@@ -403,7 +412,7 @@ xvisual:
 
       config = CALLOC_STRUCT(GLX_egl_config);
 
-      _eglInitConfig(&config->Base, i+1);
+      _eglInitConfig(&config->Base, (i+1));
       SET_CONFIG_ATTRIB(&config->Base, EGL_NATIVE_VISUAL_ID, attribs.id);
       SET_CONFIG_ATTRIB(&config->Base, EGL_BUFFER_SIZE, attribs.bufferSize);
       SET_CONFIG_ATTRIB(&config->Base, EGL_RED_SIZE, attribs.redSize);
@@ -523,7 +532,10 @@ GLX_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
    if (!GLX_ctx)
       return EGL_NO_CONTEXT;
 
-   if (!_eglInitContext(drv, dpy, &GLX_ctx->Base, config, attrib_list)) {
+   conf = _eglLookupConfig(drv, dpy, config);
+   assert(conf);
+
+   if (!_eglInitContext(drv, &GLX_ctx->Base, conf, attrib_list)) {
       free(GLX_ctx);
       return EGL_NO_CONTEXT;
    }
@@ -537,9 +549,6 @@ GLX_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
       GLX_ctx_shared = GLX_egl_context(shareCtx);
    }
 
-   conf = _eglLookupConfig(drv, dpy, config);
-   assert(conf);
-
 #ifdef GLX_VERSION_1_3
    if (GLX_drv->fbconfigs)
       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);
@@ -555,7 +564,7 @@ GLX_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
       return EGL_FALSE;
 #endif
 
-   return _eglGetContextHandle(&GLX_ctx->Base);
+   return _eglLinkContext(&GLX_ctx->Base, disp);
 }
 
 
@@ -610,18 +619,22 @@ GLX_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
    _EGLDisplay *disp = _eglLookupDisplay(dpy);
    struct GLX_egl_surface *GLX_surf;
    uint width, height;
+   _EGLConfig *conf;
+
+   conf = _eglLookupConfig(drv, dpy, config);
+   assert(conf);
 
    GLX_surf = CALLOC_STRUCT(GLX_egl_surface);
    if (!GLX_surf)
       return EGL_NO_SURFACE;
 
-   if (!_eglInitSurface(drv, dpy, &GLX_surf->Base, EGL_WINDOW_BIT,
-                        config, attrib_list)) {
+   if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_WINDOW_BIT,
+                        conf, attrib_list)) {
       free(GLX_surf);
       return EGL_FALSE;
    }
 
-   _eglSaveSurface(&GLX_surf->Base);
+   _eglLinkSurface(&GLX_surf->Base, disp);
 
    GLX_surf->drawable = window;
    get_drawable_size(disp->Xdpy, window, &width, &height);
@@ -639,19 +652,23 @@ GLX_eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
    struct GLX_egl_driver *GLX_drv = GLX_egl_driver(drv);
    _EGLDisplay *disp = _eglLookupDisplay(dpy);
    struct GLX_egl_surface *GLX_surf;
+   _EGLConfig *conf;
    int i;
 
+   conf = _eglLookupConfig(drv, dpy, config);
+   assert(conf);
+
    GLX_surf = CALLOC_STRUCT(GLX_egl_surface);
    if (!GLX_surf)
       return EGL_NO_SURFACE;
 
-   if (!_eglInitSurface(drv, dpy, &GLX_surf->Base, EGL_PIXMAP_BIT,
-                        config, attrib_list)) {
+   if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_PIXMAP_BIT,
+                        conf, attrib_list)) {
       free(GLX_surf);
       return EGL_FALSE;
    }
 
-   _eglSaveSurface(&GLX_surf->Base);
+   _eglLinkSurface(&GLX_surf->Base, disp);
 
    for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
       switch (attrib_list[i]) {
@@ -674,20 +691,24 @@ GLX_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
    struct GLX_egl_driver *GLX_drv = GLX_egl_driver(drv);
    _EGLDisplay *disp = _eglLookupDisplay(dpy);
    struct GLX_egl_surface *GLX_surf;
+   _EGLConfig *conf;
    int attribs[5];
    int i = 0, j = 0;
 
+   conf = _eglLookupConfig(drv, dpy, config);
+   assert(conf);
+
    GLX_surf = CALLOC_STRUCT(GLX_egl_surface);
    if (!GLX_surf)
       return EGL_NO_SURFACE;
 
-   if (!_eglInitSurface(drv, dpy, &GLX_surf->Base, EGL_PBUFFER_BIT,
-                        config, attrib_list)) {
+   if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_PBUFFER_BIT,
+                        conf, attrib_list)) {
       free(GLX_surf);
       return EGL_NO_SURFACE;
    }
 
-   _eglSaveSurface(&GLX_surf->Base);
+   _eglLinkSurface(&GLX_surf->Base, disp);
 
    while(attrib_list[i] != EGL_NONE) {
       switch (attrib_list[i]) {
@@ -717,7 +738,7 @@ GLX_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
    _EGLSurface *surf = _eglLookupSurface(surface);
    return EGL_TRUE;
    if (surf) {
-      _eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surface);
+      _eglUnlinkSurface(surf);
       if (surf->IsBound) {
          surf->DeletePending = EGL_TRUE;
       }
@@ -788,7 +809,20 @@ GLX_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
 static _EGLProc
 GLX_eglGetProcAddress(const char *procname)
 {
-   return (_EGLProc)glXGetProcAddress((const GLubyte *)procname);   
+   /* This is a bit of a hack to get at the gallium/Mesa state tracker
+    * function st_get_proc_address().  This will probably change at
+    * some point.
+    */
+   _EGLProc (*get_proc_addr)(const char *procname);
+   get_proc_addr = dlsym(NULL, "st_get_proc_address");
+   if (get_proc_addr)
+      return get_proc_addr(procname);
+
+   get_proc_addr = glXGetProcAddress((const GLubyte *)procname);
+   if (get_proc_addr)
+      return get_proc_addr(procname);
+
+   return (_EGLProc)dlsym(NULL, procname);
 }