Browse Source

egl_glx: Clean up surface functions.

Separete Drawable and GLXDrawable.  Add support for pbuffer and pixmap
surfaces on GLX <= 1.3.  Remove surface binding code that will never
work.

Signed-off-by: Chia-I Wu <olvaffe@gmail.com>
tags/mesa_7_7_rc1
Chia-I Wu 16 years ago
parent
commit
c407c70244
1 changed files with 106 additions and 99 deletions
  1. 106
    99
      src/egl/drivers/glx/egl_glx.c

+ 106
- 99
src/egl/drivers/glx/egl_glx.c View File

@@ -33,20 +33,12 @@
* Authors: Alan Hourihane <alanh@tungstengraphics.com>
*/

/*
* TODO:
*
* test eglBind/ReleaseTexImage
*/


#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <GL/glx.h>
#include <dlfcn.h>

#include "glxclient.h"

#include "eglconfigutil.h"
#include "eglconfig.h"
#include "eglcontext.h"
@@ -117,7 +109,8 @@ struct GLX_egl_surface
{
_EGLSurface Base; /**< base class */

GLXDrawable drawable;
Drawable drawable;
GLXDrawable glx_drawable;
};


@@ -673,8 +666,8 @@ GLX_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
if (!_eglMakeCurrent(drv, disp, dsurf, rsurf, ctx))
return EGL_FALSE;

ddraw = (GLX_dsurf) ? GLX_dsurf->drawable : None;
rdraw = (GLX_rsurf) ? GLX_rsurf->drawable : None;
ddraw = (GLX_dsurf) ? GLX_dsurf->glx_drawable : None;
rdraw = (GLX_rsurf) ? GLX_rsurf->glx_drawable : None;
cctx = (GLX_ctx) ? GLX_ctx->context : NULL;

#ifdef GLX_VERSION_1_3
@@ -726,6 +719,20 @@ GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
}

GLX_surf->drawable = window;

if (GLX_dpy->have_1_3 && !GLX_dpy->glx_window_quirk)
GLX_surf->glx_drawable =
glXCreateWindow(GLX_dpy->dpy,
GLX_dpy->fbconfigs[GLX_egl_config_index(conf)],
GLX_surf->drawable, NULL);
else
GLX_surf->glx_drawable = GLX_surf->drawable;

if (!GLX_surf->glx_drawable) {
free(GLX_surf);
return NULL;
}

get_drawable_size(GLX_dpy->dpy, window, &width, &height);
GLX_surf->Base.Width = width;
GLX_surf->Base.Height = height;
@@ -733,18 +740,13 @@ GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
return &GLX_surf->Base;
}

#ifdef GLX_VERSION_1_3
static _EGLSurface *
GLX_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
NativePixmapType pixmap, const EGLint *attrib_list)
{
struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp);
struct GLX_egl_surface *GLX_surf;
int i;

/* GLX must >= 1.3 */
if (!(GLX_dpy->glx_maj == 1 && GLX_dpy->glx_min >= 3))
return NULL;
uint width, height;

GLX_surf = CALLOC_STRUCT(GLX_egl_surface);
if (!GLX_surf) {
@@ -758,25 +760,39 @@ GLX_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
return NULL;
}

for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
/* no attribs at this time */
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglCreatePixmapSurface");
free(GLX_surf);
return NULL;
GLX_surf->drawable = pixmap;

if (GLX_dpy->have_1_3) {
GLX_surf->glx_drawable =
glXCreatePixmap(GLX_dpy->dpy,
GLX_dpy->fbconfigs[GLX_egl_config_index(conf)],
GLX_surf->drawable, NULL);
}
else if (GLX_dpy->have_fbconfig) {
GLXFBConfig fbconfig = GLX_dpy->fbconfigs[GLX_egl_config_index(conf)];
XVisualInfo *vinfo = glXGetVisualFromFBConfig(GLX_dpy->dpy, fbconfig);
if (vinfo) {
GLX_surf->glx_drawable =
glXCreateGLXPixmap(GLX_dpy->dpy, vinfo, GLX_surf->drawable);
XFree(vinfo);
}
}
else {
GLX_surf->glx_drawable =
glXCreateGLXPixmap(GLX_dpy->dpy,
&GLX_dpy->visuals[GLX_egl_config_index(conf)],
GLX_surf->drawable);
}

GLX_surf->drawable =
glXCreatePixmap(GLX_dpy->dpy,
GLX_dpy->fbconfigs[GLX_egl_config_index(conf)],
pixmap, NULL);
if (!GLX_surf->drawable) {
if (!GLX_surf->glx_drawable) {
free(GLX_surf);
return NULL;
}

get_drawable_size(GLX_dpy->dpy, pixmap, &width, &height);
GLX_surf->Base.Width = width;
GLX_surf->Base.Height = height;

return &GLX_surf->Base;
}

@@ -787,11 +803,7 @@ GLX_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *disp,
struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp);
struct GLX_egl_surface *GLX_surf;
int attribs[5];
int i = 0, j = 0;

/* GLX must >= 1.3 */
if (!(GLX_dpy->glx_maj == 1 && GLX_dpy->glx_min >= 3))
return NULL;
int i;

GLX_surf = CALLOC_STRUCT(GLX_egl_surface);
if (!GLX_surf) {
@@ -805,33 +817,44 @@ GLX_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *disp,
return NULL;
}

while(attrib_list[i] != EGL_NONE) {
switch (attrib_list[i]) {
case EGL_WIDTH:
attribs[j++] = GLX_PBUFFER_WIDTH;
attribs[j++] = attrib_list[i+1];
break;
case EGL_HEIGHT:
attribs[j++] = GLX_PBUFFER_HEIGHT;
attribs[j++] = attrib_list[i+1];
break;
i = 0;
attribs[i] = None;

GLX_surf->drawable = None;

if (GLX_dpy->have_1_3) {
/* put geometry in attribs */
if (GLX_surf->Base.Width) {
attribs[i++] = GLX_PBUFFER_WIDTH;
attribs[i++] = GLX_surf->Base.Width;
}
if (GLX_surf->Base.Height) {
attribs[i++] = GLX_PBUFFER_HEIGHT;
attribs[i++] = GLX_surf->Base.Height;
}
i++;
attribs[i] = None;

GLX_surf->glx_drawable =
glXCreatePbuffer(GLX_dpy->dpy,
GLX_dpy->fbconfigs[GLX_egl_config_index(conf)],
attribs);
}
else if (GLX_dpy->have_pbuffer) {
GLX_surf->glx_drawable = GLX_dpy->glXCreateGLXPbufferSGIX(
GLX_dpy->dpy,
GLX_dpy->fbconfigs[GLX_egl_config_index(conf)],
GLX_surf->Base.Width,
GLX_surf->Base.Height,
attribs);
}
attribs[j++] = 0;

GLX_surf->drawable =
glXCreatePbuffer(GLX_dpy->dpy,
GLX_dpy->fbconfigs[GLX_egl_config_index(conf)],
attribs);
if (!GLX_surf->drawable) {
if (!GLX_surf->glx_drawable) {
free(GLX_surf);
return NULL;
}

return &GLX_surf->Base;
}
#endif

static EGLBoolean
GLX_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
@@ -839,15 +862,35 @@ GLX_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp);
if (!_eglIsSurfaceBound(surf)) {
struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf);
switch (surf->Type) {
case EGL_PBUFFER_BIT:
glXDestroyPbuffer(GLX_dpy->dpy, GLX_surf->drawable);
break;
case EGL_PIXMAP_BIT:
glXDestroyPixmap(GLX_dpy->dpy, GLX_surf->drawable);
break;
default:
break;

if (GLX_dpy->have_1_3) {
switch (surf->Type) {
case EGL_WINDOW_BIT:
if (!GLX_dpy->glx_window_quirk)
glXDestroyWindow(GLX_dpy->dpy, GLX_surf->glx_drawable);
break;
case EGL_PBUFFER_BIT:
glXDestroyPbuffer(GLX_dpy->dpy, GLX_surf->glx_drawable);
break;
case EGL_PIXMAP_BIT:
glXDestroyPixmap(GLX_dpy->dpy, GLX_surf->glx_drawable);
break;
default:
break;
}
}
else {
switch (surf->Type) {
case EGL_PBUFFER_BIT:
GLX_dpy->glXDestroyGLXPbufferSGIX(GLX_dpy->dpy,
GLX_surf->glx_drawable);
break;
case EGL_PIXMAP_BIT:
glXDestroyGLXPixmap(GLX_dpy->dpy, GLX_surf->glx_drawable);
break;
default:
break;
}
}
free(surf);
}
@@ -856,45 +899,13 @@ GLX_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
}


static EGLBoolean
GLX_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
EGLint buffer)
{
struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp);
struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf);

/* buffer ?? */
glXBindTexImageEXT(GLX_dpy->dpy, GLX_surf->drawable,
GLX_FRONT_LEFT_EXT, NULL);

return EGL_TRUE;
}


static EGLBoolean
GLX_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
EGLint buffer)
{
struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp);
struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf);

/* buffer ?? */
glXReleaseTexImageEXT(GLX_dpy->dpy, GLX_surf->drawable,
GLX_FRONT_LEFT_EXT);

return EGL_TRUE;
}


static EGLBoolean
GLX_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
{
struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp);
struct GLX_egl_surface *GLX_surf = GLX_egl_surface(draw);

_eglLog(_EGL_DEBUG, "GLX: EGL SwapBuffers 0x%x",draw);

glXSwapBuffers(GLX_dpy->dpy, GLX_surf->drawable);
glXSwapBuffers(GLX_dpy->dpy, GLX_surf->glx_drawable);

return EGL_TRUE;
}
@@ -949,13 +960,9 @@ _eglMain(const char *args)
GLX_drv->Base.API.CreateContext = GLX_eglCreateContext;
GLX_drv->Base.API.MakeCurrent = GLX_eglMakeCurrent;
GLX_drv->Base.API.CreateWindowSurface = GLX_eglCreateWindowSurface;
#ifdef GLX_VERSION_1_3
GLX_drv->Base.API.CreatePixmapSurface = GLX_eglCreatePixmapSurface;
GLX_drv->Base.API.CreatePbufferSurface = GLX_eglCreatePbufferSurface;
#endif
GLX_drv->Base.API.DestroySurface = GLX_eglDestroySurface;
GLX_drv->Base.API.BindTexImage = GLX_eglBindTexImage;
GLX_drv->Base.API.ReleaseTexImage = GLX_eglReleaseTexImage;
GLX_drv->Base.API.SwapBuffers = GLX_eglSwapBuffers;
GLX_drv->Base.API.GetProcAddress = GLX_eglGetProcAddress;


Loading…
Cancel
Save