mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 16:08:04 +02:00
egl: Add new EGL driver that wraps GLX.
This commit is contained in:
parent
d142f216d2
commit
8015f3ae3b
2 changed files with 648 additions and 0 deletions
74
src/egl/drivers/glx/Makefile
Normal file
74
src/egl/drivers/glx/Makefile
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# src/egl/drivers/glx/Makefile
|
||||
|
||||
# Build XEGL DRI driver loader library: egl_glx.so
|
||||
|
||||
|
||||
TOP = ../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
|
||||
EXTRA_DEFINES = -DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\"
|
||||
|
||||
DRIVER_NAME = egl_glx.so
|
||||
|
||||
|
||||
INCLUDE_DIRS = \
|
||||
-I. \
|
||||
-I/usr/include \
|
||||
$(shell pkg-config --cflags-only-I libdrm) \
|
||||
-I$(TOP)/include \
|
||||
-I$(TOP)/include/GL/internal \
|
||||
-I$(TOP)/src/mesa/glapi \
|
||||
-I$(TOP)/src/mesa/drivers/dri/common \
|
||||
-I$(TOP)/src/mesa/main \
|
||||
-I$(TOP)/src/mesa \
|
||||
-I$(TOP)/src/egl/main \
|
||||
-I$(TOP)/src/glx/x11
|
||||
|
||||
SOURCES = egl_glx.c
|
||||
|
||||
OBJECTS = $(SOURCES:.c=.o)
|
||||
|
||||
DRM_LIB = `pkg-config --libs libdrm`
|
||||
|
||||
MISC_LIBS = -ldl -lXext -lGL
|
||||
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(EXTRA_DEFINES) $< -o $@
|
||||
|
||||
|
||||
.PHONY: library
|
||||
|
||||
|
||||
default: depend library Makefile
|
||||
|
||||
|
||||
library: $(TOP)/$(LIB_DIR)/$(DRIVER_NAME)
|
||||
|
||||
|
||||
# Make the egl_glx.so library
|
||||
$(TOP)/$(LIB_DIR)/$(DRIVER_NAME): $(OBJECTS)
|
||||
$(TOP)/bin/mklib -o $(DRIVER_NAME) \
|
||||
-noprefix \
|
||||
-major 1 -minor 0 \
|
||||
-L$(TOP)/$(LIB_DIR) \
|
||||
-install $(TOP)/$(LIB_DIR) \
|
||||
$(OBJECTS) $(DRM_LIB) $(MISC_LIBS)
|
||||
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
rm -f *.so
|
||||
rm -f depend depend.bak
|
||||
|
||||
|
||||
depend: $(SOURCES) $(HEADERS)
|
||||
@ echo "running $(MKDEP)"
|
||||
@ rm -f depend
|
||||
@ touch depend
|
||||
$(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) \
|
||||
$(SOURCES) $(HEADERS) >/dev/null 2>/dev/null
|
||||
|
||||
include depend
|
||||
# DO NOT DELETE
|
||||
574
src/egl/drivers/glx/egl_glx.c
Normal file
574
src/egl/drivers/glx/egl_glx.c
Normal file
|
|
@ -0,0 +1,574 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* This is an EGL driver that wraps GLX. This gives the benefit of being
|
||||
* completely agnostic of the direct rendering implementation.
|
||||
*
|
||||
* Authors: Alan Hourihane <alanh@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
*
|
||||
* Add GLXFBConfig support
|
||||
* Pbuffer & Pixmap support
|
||||
* test eglBind/ReleaseTexImage
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include "dlfcn.h"
|
||||
#include <X11/Xlib.h>
|
||||
#include <GL/gl.h>
|
||||
#include "glxclient.h"
|
||||
|
||||
#define _EGL_PLATFORM_X
|
||||
|
||||
#include "eglconfig.h"
|
||||
#include "eglcontext.h"
|
||||
#include "egldisplay.h"
|
||||
#include "egldriver.h"
|
||||
#include "eglglobals.h"
|
||||
#include "eglhash.h"
|
||||
#include "egllog.h"
|
||||
#include "eglsurface.h"
|
||||
|
||||
#include <GL/gl.h>
|
||||
|
||||
#define CALLOC_STRUCT(T) (struct T *) calloc(1, sizeof(struct T))
|
||||
|
||||
static const EGLint all_apis = (EGL_OPENGL_ES_BIT |
|
||||
EGL_OPENGL_ES2_BIT |
|
||||
EGL_OPENVG_BIT |
|
||||
EGL_OPENGL_BIT);
|
||||
|
||||
struct visual_attribs
|
||||
{
|
||||
/* X visual attribs */
|
||||
int id;
|
||||
int klass;
|
||||
int depth;
|
||||
int redMask, greenMask, blueMask;
|
||||
int colormapSize;
|
||||
int bitsPerRGB;
|
||||
|
||||
/* GL visual attribs */
|
||||
int supportsGL;
|
||||
int transparentType;
|
||||
int transparentRedValue;
|
||||
int transparentGreenValue;
|
||||
int transparentBlueValue;
|
||||
int transparentAlphaValue;
|
||||
int transparentIndexValue;
|
||||
int bufferSize;
|
||||
int level;
|
||||
int render_type;
|
||||
int doubleBuffer;
|
||||
int stereo;
|
||||
int auxBuffers;
|
||||
int redSize, greenSize, blueSize, alphaSize;
|
||||
int depthSize;
|
||||
int stencilSize;
|
||||
int accumRedSize, accumGreenSize, accumBlueSize, accumAlphaSize;
|
||||
int numSamples, numMultisample;
|
||||
int visualCaveat;
|
||||
};
|
||||
|
||||
/** subclass of _EGLDriver */
|
||||
struct GLX_egl_driver
|
||||
{
|
||||
_EGLDriver Base; /**< base class */
|
||||
|
||||
XVisualInfo *visuals;
|
||||
|
||||
/* GLXFBConfig *fbconfigs - todo */
|
||||
};
|
||||
|
||||
|
||||
/** subclass of _EGLContext */
|
||||
struct GLX_egl_context
|
||||
{
|
||||
_EGLContext Base; /**< base class */
|
||||
|
||||
GLXContext context;
|
||||
};
|
||||
|
||||
|
||||
/** subclass of _EGLSurface */
|
||||
struct GLX_egl_surface
|
||||
{
|
||||
_EGLSurface Base; /**< base class */
|
||||
|
||||
GLXDrawable drawable;
|
||||
};
|
||||
|
||||
|
||||
/** subclass of _EGLConfig */
|
||||
struct GLX_egl_config
|
||||
{
|
||||
_EGLConfig Base; /**< base class */
|
||||
};
|
||||
|
||||
/** cast wrapper */
|
||||
static struct GLX_egl_driver *
|
||||
GLX_egl_driver(_EGLDriver *drv)
|
||||
{
|
||||
return (struct GLX_egl_driver *) drv;
|
||||
}
|
||||
|
||||
static struct GLX_egl_context *
|
||||
GLX_egl_context(_EGLContext *ctx)
|
||||
{
|
||||
return (struct GLX_egl_context *) ctx;
|
||||
}
|
||||
|
||||
static struct GLX_egl_surface *
|
||||
GLX_egl_surface(_EGLSurface *surf)
|
||||
{
|
||||
return (struct GLX_egl_surface *) surf;
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
get_visual_attribs(Display *dpy, XVisualInfo *vInfo,
|
||||
struct visual_attribs *attribs)
|
||||
{
|
||||
const char *ext = glXQueryExtensionsString(dpy, vInfo->screen);
|
||||
int rgba;
|
||||
|
||||
memset(attribs, 0, sizeof(struct visual_attribs));
|
||||
|
||||
attribs->id = vInfo->visualid;
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
attribs->klass = vInfo->c_class;
|
||||
#else
|
||||
attribs->klass = vInfo->class;
|
||||
#endif
|
||||
attribs->depth = vInfo->depth;
|
||||
attribs->redMask = vInfo->red_mask;
|
||||
attribs->greenMask = vInfo->green_mask;
|
||||
attribs->blueMask = vInfo->blue_mask;
|
||||
attribs->colormapSize = vInfo->colormap_size;
|
||||
attribs->bitsPerRGB = vInfo->bits_per_rgb;
|
||||
|
||||
if (glXGetConfig(dpy, vInfo, GLX_USE_GL, &attribs->supportsGL) != 0 ||
|
||||
!attribs->supportsGL)
|
||||
return GL_FALSE;
|
||||
glXGetConfig(dpy, vInfo, GLX_BUFFER_SIZE, &attribs->bufferSize);
|
||||
glXGetConfig(dpy, vInfo, GLX_LEVEL, &attribs->level);
|
||||
glXGetConfig(dpy, vInfo, GLX_RGBA, &rgba);
|
||||
if (!rgba)
|
||||
return GL_FALSE;
|
||||
attribs->render_type = GLX_RGBA_BIT;
|
||||
|
||||
glXGetConfig(dpy, vInfo, GLX_DOUBLEBUFFER, &attribs->doubleBuffer);
|
||||
glXGetConfig(dpy, vInfo, GLX_STEREO, &attribs->stereo);
|
||||
glXGetConfig(dpy, vInfo, GLX_AUX_BUFFERS, &attribs->auxBuffers);
|
||||
glXGetConfig(dpy, vInfo, GLX_RED_SIZE, &attribs->redSize);
|
||||
glXGetConfig(dpy, vInfo, GLX_GREEN_SIZE, &attribs->greenSize);
|
||||
glXGetConfig(dpy, vInfo, GLX_BLUE_SIZE, &attribs->blueSize);
|
||||
glXGetConfig(dpy, vInfo, GLX_ALPHA_SIZE, &attribs->alphaSize);
|
||||
glXGetConfig(dpy, vInfo, GLX_DEPTH_SIZE, &attribs->depthSize);
|
||||
glXGetConfig(dpy, vInfo, GLX_STENCIL_SIZE, &attribs->stencilSize);
|
||||
glXGetConfig(dpy, vInfo, GLX_ACCUM_RED_SIZE, &attribs->accumRedSize);
|
||||
glXGetConfig(dpy, vInfo, GLX_ACCUM_GREEN_SIZE, &attribs->accumGreenSize);
|
||||
glXGetConfig(dpy, vInfo, GLX_ACCUM_BLUE_SIZE, &attribs->accumBlueSize);
|
||||
glXGetConfig(dpy, vInfo, GLX_ACCUM_ALPHA_SIZE, &attribs->accumAlphaSize);
|
||||
|
||||
/* get transparent pixel stuff */
|
||||
glXGetConfig(dpy, vInfo,GLX_TRANSPARENT_TYPE, &attribs->transparentType);
|
||||
if (attribs->transparentType == GLX_TRANSPARENT_RGB) {
|
||||
glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_RED_VALUE, &attribs->transparentRedValue);
|
||||
glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_GREEN_VALUE, &attribs->transparentGreenValue);
|
||||
glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_BLUE_VALUE, &attribs->transparentBlueValue);
|
||||
glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_ALPHA_VALUE, &attribs->transparentAlphaValue);
|
||||
}
|
||||
else if (attribs->transparentType == GLX_TRANSPARENT_INDEX) {
|
||||
glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_INDEX_VALUE, &attribs->transparentIndexValue);
|
||||
}
|
||||
|
||||
/* multisample attribs */
|
||||
#ifdef GLX_ARB_multisample
|
||||
if (ext && strstr(ext, "GLX_ARB_multisample")) {
|
||||
glXGetConfig(dpy, vInfo, GLX_SAMPLE_BUFFERS_ARB, &attribs->numMultisample);
|
||||
glXGetConfig(dpy, vInfo, GLX_SAMPLES_ARB, &attribs->numSamples);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
attribs->numSamples = 0;
|
||||
attribs->numMultisample = 0;
|
||||
}
|
||||
|
||||
#if defined(GLX_EXT_visual_rating)
|
||||
if (ext && strstr(ext, "GLX_EXT_visual_rating")) {
|
||||
glXGetConfig(dpy, vInfo, GLX_VISUAL_CAVEAT_EXT, &attribs->visualCaveat);
|
||||
}
|
||||
else {
|
||||
attribs->visualCaveat = GLX_NONE_EXT;
|
||||
}
|
||||
#else
|
||||
attribs->visualCaveat = 0;
|
||||
#endif
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
static EGLBoolean
|
||||
create_configs(_EGLDisplay *disp, struct GLX_egl_driver *GLX_drv)
|
||||
{
|
||||
XVisualInfo theTemplate;
|
||||
int numVisuals;
|
||||
long mask;
|
||||
int i;
|
||||
struct visual_attribs attribs;
|
||||
|
||||
/* get list of all visuals on this screen */
|
||||
theTemplate.screen = DefaultScreen(disp->Xdpy);
|
||||
mask = VisualScreenMask;
|
||||
GLX_drv->visuals = XGetVisualInfo(disp->Xdpy, mask, &theTemplate, &numVisuals);
|
||||
|
||||
for (i = 0; i < numVisuals; i++) {
|
||||
struct GLX_egl_config *config;
|
||||
|
||||
if (!get_visual_attribs(disp->Xdpy, &GLX_drv->visuals[i], &attribs))
|
||||
continue;
|
||||
|
||||
if (attribs.doubleBuffer) {
|
||||
config = CALLOC_STRUCT(GLX_egl_config);
|
||||
|
||||
_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);
|
||||
SET_CONFIG_ATTRIB(&config->Base, EGL_GREEN_SIZE, attribs.greenSize);
|
||||
SET_CONFIG_ATTRIB(&config->Base, EGL_BLUE_SIZE, attribs.blueSize);
|
||||
SET_CONFIG_ATTRIB(&config->Base, EGL_ALPHA_SIZE, attribs.alphaSize);
|
||||
SET_CONFIG_ATTRIB(&config->Base, EGL_DEPTH_SIZE, attribs.depthSize);
|
||||
SET_CONFIG_ATTRIB(&config->Base, EGL_STENCIL_SIZE, attribs.stencilSize);
|
||||
SET_CONFIG_ATTRIB(&config->Base, EGL_SAMPLES, attribs.numSamples);
|
||||
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*/));
|
||||
|
||||
/* XXX possibly other things to init... */
|
||||
|
||||
_eglAddConfig(disp, &config->Base);
|
||||
}
|
||||
}
|
||||
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called via eglInitialize(), GLX_drv->API.Initialize().
|
||||
*/
|
||||
static EGLBoolean
|
||||
GLX_eglInitialize(_EGLDriver *drv, EGLDisplay dpy,
|
||||
EGLint *minor, EGLint *major)
|
||||
{
|
||||
struct GLX_egl_driver *GLX_drv = GLX_egl_driver(drv);
|
||||
_EGLDisplay *disp = _eglLookupDisplay(dpy);
|
||||
|
||||
_eglLog(_EGL_DEBUG, "XDRI: eglInitialize");
|
||||
|
||||
if (!disp->Xdpy) {
|
||||
disp->Xdpy = XOpenDisplay(NULL);
|
||||
if (!disp->Xdpy) {
|
||||
_eglLog(_EGL_WARNING, "XDRI: XOpenDisplay failed");
|
||||
return EGL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
GLX_drv->Base.Initialized = EGL_TRUE;
|
||||
|
||||
GLX_drv->Base.Name = "GLX";
|
||||
|
||||
/* we're supporting EGL 1.4 */
|
||||
*minor = 1;
|
||||
*major = 4;
|
||||
|
||||
create_configs(disp, GLX_drv);
|
||||
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called via eglTerminate(), drv->API.Terminate().
|
||||
*/
|
||||
static EGLBoolean
|
||||
GLX_eglTerminate(_EGLDriver *drv, EGLDisplay dpy)
|
||||
{
|
||||
_EGLDisplay *disp = _eglLookupDisplay(dpy);
|
||||
|
||||
_eglLog(_EGL_DEBUG, "XDRI: eglTerminate");
|
||||
|
||||
// XCloseDisplay(disp->Xdpy);
|
||||
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called via eglCreateContext(), drv->API.CreateContext().
|
||||
*/
|
||||
static EGLContext
|
||||
GLX_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
|
||||
EGLContext share_list, const EGLint *attrib_list)
|
||||
{
|
||||
_EGLDisplay *disp = _eglLookupDisplay(dpy);
|
||||
struct GLX_egl_context *GLX_ctx = CALLOC_STRUCT(GLX_egl_context);
|
||||
struct GLX_egl_driver *GLX_drv = GLX_egl_driver(drv);
|
||||
struct GLX_egl_context *GLX_ctx_shared = NULL;
|
||||
_EGLConfig *conf;
|
||||
|
||||
if (!GLX_ctx)
|
||||
return EGL_NO_CONTEXT;
|
||||
|
||||
if (!_eglInitContext(drv, dpy, &GLX_ctx->Base, config, attrib_list)) {
|
||||
free(GLX_ctx);
|
||||
return EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
if (share_list != EGL_NO_CONTEXT) {
|
||||
_EGLContext *shareCtx = _eglLookupContext(share_list);
|
||||
if (!shareCtx) {
|
||||
_eglError(EGL_BAD_CONTEXT, "eglCreateContext(share_list)");
|
||||
return EGL_FALSE;
|
||||
}
|
||||
GLX_ctx_shared = GLX_egl_context(shareCtx);
|
||||
}
|
||||
|
||||
conf = _eglLookupConfig(drv, dpy, config);
|
||||
assert(conf);
|
||||
|
||||
GLX_ctx->context = glXCreateContext(disp->Xdpy, &GLX_drv->visuals[(int)config-1], GLX_ctx_shared ? GLX_ctx_shared->context : NULL, GL_TRUE);
|
||||
if (!GLX_ctx->context)
|
||||
return EGL_FALSE;
|
||||
|
||||
/* need to have a direct rendering context */
|
||||
if (!glXIsDirect(disp->Xdpy, GLX_ctx->context))
|
||||
return EGL_FALSE;
|
||||
|
||||
return _eglGetContextHandle(&GLX_ctx->Base);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called via eglMakeCurrent(), drv->API.MakeCurrent().
|
||||
*/
|
||||
static EGLBoolean
|
||||
GLX_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
|
||||
EGLSurface r, EGLContext context)
|
||||
{
|
||||
_EGLDisplay *disp = _eglLookupDisplay(dpy);
|
||||
_EGLContext *ctx = _eglLookupContext(context);
|
||||
_EGLSurface *dsurf = _eglLookupSurface(d);
|
||||
_EGLSurface *rsurf = _eglLookupSurface(r);
|
||||
struct GLX_egl_surface *GLX_dsurf = GLX_egl_surface(dsurf);
|
||||
struct GLX_egl_surface *GLX_rsurf = GLX_egl_surface(rsurf);
|
||||
struct GLX_egl_context *GLX_ctx = GLX_egl_context(ctx);
|
||||
|
||||
if (!_eglMakeCurrent(drv, dpy, d, r, context))
|
||||
return EGL_FALSE;
|
||||
|
||||
// if (!glXMakeContextCurrent(disp->Xdpy, GLX_dsurf->drawable, GLX_rsurf->drawable, GLX_ctx->context))
|
||||
if (!glXMakeCurrent(disp->Xdpy, GLX_dsurf ? GLX_dsurf->drawable : 0, GLX_ctx ? GLX_ctx->context : NULL))
|
||||
return EGL_FALSE;
|
||||
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
/** Get size of given window */
|
||||
static Status
|
||||
get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height)
|
||||
{
|
||||
Window root;
|
||||
Status stat;
|
||||
int xpos, ypos;
|
||||
unsigned int w, h, bw, depth;
|
||||
stat = XGetGeometry(dpy, d, &root, &xpos, &ypos, &w, &h, &bw, &depth);
|
||||
*width = w;
|
||||
*height = h;
|
||||
return stat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
|
||||
*/
|
||||
static EGLSurface
|
||||
GLX_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
|
||||
NativeWindowType window, const EGLint *attrib_list)
|
||||
{
|
||||
_EGLDisplay *disp = _eglLookupDisplay(dpy);
|
||||
struct GLX_egl_surface *GLX_surf;
|
||||
uint width, height;
|
||||
|
||||
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)) {
|
||||
free(GLX_surf);
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
_eglSaveSurface(&GLX_surf->Base);
|
||||
|
||||
GLX_surf->drawable = window;
|
||||
get_drawable_size(disp->Xdpy, window, &width, &height);
|
||||
GLX_surf->Base.Width = width;
|
||||
GLX_surf->Base.Height = height;
|
||||
|
||||
return _eglGetSurfaceHandle(&GLX_surf->Base);
|
||||
}
|
||||
|
||||
static EGLBoolean
|
||||
GLX_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
|
||||
{
|
||||
_EGLDisplay *disp = _eglLookupDisplay(dpy);
|
||||
_EGLSurface *surf = _eglLookupSurface(surface);
|
||||
return EGL_TRUE;
|
||||
if (surf) {
|
||||
_eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surface);
|
||||
if (surf->IsBound) {
|
||||
surf->DeletePending = EGL_TRUE;
|
||||
}
|
||||
else {
|
||||
free(surf);
|
||||
}
|
||||
|
||||
return EGL_TRUE;
|
||||
}
|
||||
else {
|
||||
_eglError(EGL_BAD_SURFACE, "eglDestroySurface");
|
||||
return EGL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static EGLBoolean
|
||||
GLX_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
|
||||
EGLint buffer)
|
||||
{
|
||||
_EGLDisplay *disp = _eglLookupDisplay(dpy);
|
||||
_EGLSurface *surf = _eglLookupSurface(surface);
|
||||
struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf);
|
||||
|
||||
/* buffer ?? */
|
||||
glXBindTexImageEXT(disp->Xdpy, GLX_surf->drawable, GLX_FRONT_LEFT_EXT, NULL);
|
||||
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
static EGLBoolean
|
||||
GLX_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
|
||||
EGLint buffer)
|
||||
{
|
||||
_EGLDisplay *disp = _eglLookupDisplay(dpy);
|
||||
_EGLSurface *surf = _eglLookupSurface(surface);
|
||||
struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf);
|
||||
|
||||
/* buffer ?? */
|
||||
glXReleaseTexImageEXT(disp->Xdpy, GLX_surf->drawable, GLX_FRONT_LEFT_EXT);
|
||||
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
static EGLBoolean
|
||||
GLX_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
|
||||
{
|
||||
_EGLDisplay *disp = _eglLookupDisplay(dpy);
|
||||
_EGLSurface *surf = _eglLookupSurface(draw);
|
||||
struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf);
|
||||
|
||||
_eglLog(_EGL_DEBUG, "XDRI: EGL SwapBuffers 0x%x",draw);
|
||||
|
||||
/* error checking step: */
|
||||
if (!_eglSwapBuffers(drv, dpy, draw))
|
||||
return EGL_FALSE;
|
||||
|
||||
glXSwapBuffers(disp->Xdpy, GLX_surf->drawable);
|
||||
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called from eglGetProcAddress() via drv->API.GetProcAddress().
|
||||
*/
|
||||
static _EGLProc
|
||||
GLX_eglGetProcAddress(const char *procname)
|
||||
{
|
||||
return (_EGLProc)glXGetProcAddress((const GLubyte *)procname);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is the main entrypoint into the driver, called by libEGL.
|
||||
* Create a new _EGLDriver object and init its dispatch table.
|
||||
*/
|
||||
_EGLDriver *
|
||||
_eglMain(_EGLDisplay *disp, const char *args)
|
||||
{
|
||||
struct GLX_egl_driver *GLX_drv = CALLOC_STRUCT(GLX_egl_driver);
|
||||
if (!GLX_drv)
|
||||
return NULL;
|
||||
|
||||
_eglInitDriverFallbacks(&GLX_drv->Base);
|
||||
GLX_drv->Base.API.Initialize = GLX_eglInitialize;
|
||||
GLX_drv->Base.API.Terminate = GLX_eglTerminate;
|
||||
GLX_drv->Base.API.CreateContext = GLX_eglCreateContext;
|
||||
GLX_drv->Base.API.MakeCurrent = GLX_eglMakeCurrent;
|
||||
GLX_drv->Base.API.CreateWindowSurface = GLX_eglCreateWindowSurface;
|
||||
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;
|
||||
|
||||
GLX_drv->Base.ClientAPIsMask = all_apis;
|
||||
GLX_drv->Base.Name = "GLX";
|
||||
|
||||
_eglLog(_EGL_DEBUG, "GLX: main(%s)", args);
|
||||
|
||||
/* set new DRI path to pick up EGL version (no mesa code), but don't
|
||||
* override if one is already set.
|
||||
*/
|
||||
setenv("LIBGL_DRIVERS_PATH", DEFAULT_DRIVER_DIR"/egl", 0);
|
||||
|
||||
return &GLX_drv->Base;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue