static EGLBoolean
dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp)
{
+ /* not until swrast_dri is supported */
+ if (disp->Options.UseFallback)
+ return EGL_FALSE;
+
switch (disp->Platform) {
case _EGL_PLATFORM_X11:
if (disp->Options.TestOnly)
if (disp->Platform != _EGL_PLATFORM_X11)
return EGL_FALSE;
+ /* this is a fallback driver */
+ if (!disp->Options.UseFallback)
+ return EGL_FALSE;
+
if (disp->Options.TestOnly)
return EGL_TRUE;
/* options that affect how the driver initializes the display */
struct {
EGLBoolean TestOnly; /**< Driver should not set fields when true */
+ EGLBoolean UseFallback; /**< Use fallback driver (sw or less features) */
} Options;
/* these fields are set by the driver during init */
/* set options */
dpy->Options.TestOnly = test_only;
+ dpy->Options.UseFallback = EGL_FALSE;
best_drv = _eglMatchAndInitialize(dpy);
+ if (!best_drv) {
+ dpy->Options.UseFallback = EGL_TRUE;
+ best_drv = _eglMatchAndInitialize(dpy);
+ }
_eglUnlockMutex(&_eglModuleMutex);
#include "egl_g3d_loader.h"
#include "native.h"
+static void
+egl_g3d_invalid_surface(struct native_display *ndpy,
+ struct native_surface *nsurf,
+ unsigned int seq_num)
+{
+ /* XXX not thread safe? */
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data);
+ struct egl_g3d_context *gctx;
+
+ /*
+ * Some functions such as egl_g3d_copy_buffers create a temporary native
+ * surface. There is no gsurf associated with it.
+ */
+ gctx = (gsurf) ? egl_g3d_context(gsurf->base.CurrentContext) : NULL;
+ if (gctx)
+ gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gsurf->stfbi);
+}
+
+static struct pipe_screen *
+egl_g3d_new_drm_screen(struct native_display *ndpy, const char *name, int fd)
+{
+ _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ return gdpy->loader->create_drm_screen(name, fd);
+}
+
+static struct pipe_screen *
+egl_g3d_new_sw_screen(struct native_display *ndpy, struct sw_winsys *ws)
+{
+ _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ return gdpy->loader->create_sw_screen(ws);
+}
+
+static struct native_event_handler egl_g3d_native_event_handler = {
+ egl_g3d_invalid_surface,
+ egl_g3d_new_drm_screen,
+ egl_g3d_new_sw_screen
+};
+
/**
* Get the native platform.
*/
break;
}
- if (!nplat)
+ if (nplat)
+ nplat->set_event_handler(&egl_g3d_native_event_handler);
+ else
_eglLog(_EGL_WARNING, "unsupported platform %s", plat_name);
gdrv->platforms[plat] = nplat;
return id;
}
-static void
-egl_g3d_invalid_surface(struct native_display *ndpy,
- struct native_surface *nsurf,
- unsigned int seq_num)
-{
- /* XXX not thread safe? */
- struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data);
- struct egl_g3d_context *gctx;
-
- /*
- * Some functions such as egl_g3d_copy_buffers create a temporary native
- * surface. There is no gsurf associated with it.
- */
- gctx = (gsurf) ? egl_g3d_context(gsurf->base.CurrentContext) : NULL;
- if (gctx)
- gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gsurf->stfbi);
-}
-
-static struct pipe_screen *
-egl_g3d_new_drm_screen(struct native_display *ndpy, const char *name, int fd)
-{
- _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
- struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
- return gdpy->loader->create_drm_screen(name, fd);
-}
-
-static struct pipe_screen *
-egl_g3d_new_sw_screen(struct native_display *ndpy, struct sw_winsys *ws)
-{
- _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
- struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
- return gdpy->loader->create_sw_screen(ws);
-}
-
-static struct native_event_handler egl_g3d_native_event_handler = {
- egl_g3d_invalid_surface,
- egl_g3d_new_drm_screen,
- egl_g3d_new_sw_screen
-};
-
static void
egl_g3d_free_config(void *conf)
{
_eglLog(_EGL_INFO, "use %s for display %p", nplat->name, dpy->PlatformDisplay);
gdpy->native = nplat->create_display(dpy->PlatformDisplay,
- &egl_g3d_native_event_handler, (void *) dpy);
+ dpy->Options.UseFallback, (void *) dpy);
if (!gdpy->native) {
_eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)");
goto fail;
struct native_platform {
const char *name;
+ void (*set_event_handler)(struct native_event_handler *handler);
struct native_display *(*create_display)(void *dpy,
- struct native_event_handler *handler,
+ boolean use_sw,
void *user_data);
};
return &drmdpy->base;
}
+static struct native_event_handler *drm_event_handler;
+
+static void
+native_set_event_handler(struct native_event_handler *event_handler)
+{
+ drm_event_handler = event_handler;
+}
+
static struct native_display *
-native_create_display(void *dpy, struct native_event_handler *event_handler,
- void *user_data)
+native_create_display(void *dpy, boolean use_sw, void *user_data)
{
int fd;
if (fd < 0)
return NULL;
- return drm_create_display(fd, event_handler, user_data);
+ return drm_create_display(fd, drm_event_handler, user_data);
}
static const struct native_platform drm_platform = {
"DRM", /* name */
+ native_set_event_handler,
native_create_display
};
return &fbdpy->base;
}
+static struct native_event_handler *fbdev_event_handler;
+
+static void
+native_set_event_handler(struct native_event_handler *event_handler)
+{
+ fbdev_event_handler = event_handler;
+}
+
static struct native_display *
-native_create_display(void *dpy, struct native_event_handler *event_handler,
- void *user_data)
+native_create_display(void *dpy, boolean use_sw, void *user_data)
{
struct native_display *ndpy;
int fd;
if (fd < 0)
return NULL;
- ndpy = fbdev_display_create(fd, event_handler, user_data);
+ ndpy = fbdev_display_create(fd, fbdev_event_handler, user_data);
if (!ndpy)
close(fd);
static const struct native_platform fbdev_platform = {
"FBDEV", /* name */
+ native_set_event_handler,
native_create_display
};
return &gdpy->base;
}
+static struct native_event_handler *gdi_event_handler;
+
+static void
+native_set_event_handler(struct native_event_handler *event_handler)
+{
+ gdi_event_handler = event_handler;
+}
+
static struct native_display *
-native_create_display(void *dpy, struct native_event_handler *event_handler,
- void *user_data)
+native_create_display(void *dpy, boolean use_sw, void *user_data)
{
- return gdi_create_display((HDC) dpy, event_handler, user_data);
+ return gdi_create_display((HDC) dpy, gdi_event_handler, user_data);
}
static const struct native_platform gdi_platform = {
"GDI", /* name */
+ native_set_event_handler,
native_create_display
};
#include "native_x11.h"
+static struct native_event_handler *x11_event_handler;
+
+static void
+native_set_event_handler(struct native_event_handler *event_handler)
+{
+ x11_event_handler = event_handler;
+}
+
static struct native_display *
-native_create_display(void *dpy, struct native_event_handler *event_handler,
- void *user_data)
+native_create_display(void *dpy, boolean use_sw, void *user_data)
{
struct native_display *ndpy = NULL;
boolean force_sw;
force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE);
- if (!force_sw) {
- ndpy = x11_create_dri2_display((Display *) dpy,
- event_handler, user_data);
- }
-
- if (!ndpy) {
- EGLint level = (force_sw) ? _EGL_INFO : _EGL_WARNING;
- _eglLog(level, "use software fallback");
+ if (force_sw || use_sw) {
+ _eglLog(_EGL_INFO, "use software fallback");
ndpy = x11_create_ximage_display((Display *) dpy,
- event_handler, user_data);
+ x11_event_handler, user_data);
+ }
+ else {
+ ndpy = x11_create_dri2_display((Display *) dpy,
+ x11_event_handler, user_data);
}
return ndpy;
static const struct native_platform x11_platform = {
"X11", /* name */
+ native_set_event_handler,
native_create_display
};