AM_CONDITIONAL(ENABLE_EGL, test x$enable_egl = xyes)
if test x$enable_egl = xyes; then
AC_DEFINE([ENABLE_EGL], [1], [Build Weston with EGL support])
- COMPOSITOR_MODULES="$COMPOSITOR_MODULES egl >= 7.10 glesv2"
+ PKG_CHECK_MODULES(EGL, [egl >= 7.10 glesv2])
fi
AC_ARG_ENABLE(xkbcommon,
subsurface-server-protocol.h \
bindings.c \
animation.c \
- gl-renderer.h \
noop-renderer.c \
pixman-renderer.c \
pixman-renderer.h \
weston-launch.h \
weston-egl-ext.h
-if ENABLE_EGL
-weston_SOURCES += \
- gl-renderer.c \
- vertex-clipping.c \
- vertex-clipping.h
-endif
-
git-version.h : .FORCE
$(AM_V_GEN)(echo "#define BUILD_ID \"$(shell git --git-dir=$(top_srcdir)/.git describe --always --dirty) $(shell git --git-dir=$(top_srcdir)/.git log -1 --format='%s (%ci)')\"" > $@-new; \
cmp -s $@ $@-new || cp $@-new $@; \
$(tablet_shell) \
$(cms_static) \
$(cms_colord) \
+ $(gl_renderer) \
$(x11_backend) \
$(drm_backend) \
$(wayland_backend) \
noinst_LTLIBRARIES += $(rpi_backend)
endif
+if ENABLE_EGL
+gl_renderer = gl-renderer.la
+gl_renderer_la_LDFLAGS = -module -avoid-version
+gl_renderer_la_LIBADD = $(COMPOSITOR_LIBS) $(EGL_LIBS)
+gl_renderer_la_CFLAGS = \
+ $(COMPOSITOR_CFLAGS) \
+ $(EGL_CFLAGS) \
+ $(GCC_CFLAGS)
+gl_renderer_la_SOURCES = \
+ gl-renderer.h \
+ gl-renderer.c \
+ vertex-clipping.c \
+ vertex-clipping.h
+endif
+
if ENABLE_X11_COMPOSITOR
x11_backend = x11-backend.la
x11_backend_la_LDFLAGS = -module -avoid-version
../shared/libshared-cairo.la
x11_backend_la_CFLAGS = \
$(COMPOSITOR_CFLAGS) \
+ $(EGL_CFLAGS) \
$(PIXMAN_CFLAGS) \
$(CAIRO_CFLAGS) \
$(X11_COMPOSITOR_CFLAGS) \
../shared/libshared.la -lrt
drm_backend_la_CFLAGS = \
$(COMPOSITOR_CFLAGS) \
+ $(EGL_CFLAGS) \
$(DRM_COMPOSITOR_CFLAGS) \
$(GCC_CFLAGS)
drm_backend_la_SOURCES = \
../shared/libshared-cairo.la
wayland_backend_la_CFLAGS = \
$(COMPOSITOR_CFLAGS) \
+ $(EGL_CFLAGS) \
$(PIXMAN_CFLAGS) \
$(CAIRO_CFLAGS) \
$(WAYLAND_COMPOSITOR_CFLAGS) \
../shared/libshared.la
fbdev_backend_la_CFLAGS = \
$(COMPOSITOR_CFLAGS) \
+ $(EGL_CFLAGS) \
$(FBDEV_COMPOSITOR_CFLAGS) \
$(PIXMAN_CFLAGS) \
$(GCC_CFLAGS)
#include <linux/vt.h>
#include <assert.h>
#include <sys/mman.h>
+#include <dlfcn.h>
#include <time.h>
#include <xf86drm.h>
uint32_t formats[];
};
+static struct gl_renderer_interface *gl_renderer;
+
static const char default_seat[] = "seat0";
static void
if (c->use_pixman) {
drm_output_fini_pixman(output);
} else {
- gl_renderer_output_destroy(output_base);
+ gl_renderer->output_destroy(output_base);
gbm_surface_destroy(output->surface);
}
return -1;
}
} else {
- gl_renderer_output_destroy(&output->base);
+ gl_renderer->output_destroy(&output->base);
gbm_surface_destroy(output->surface);
if (drm_output_init_egl(output, ec) < 0) {
{
EGLint format;
+ gl_renderer = weston_load_module("gl-renderer.so",
+ "gl_renderer_interface");
+ if (!gl_renderer)
+ return -1;
+
+ /* GBM will load a dri driver, but even though they need symbols from
+ * libglapi, in some version of Mesa they are not linked to it. Since
+ * only the gl-renderer module links to it, the call above won't make
+ * these symbols globally available, and loading the DRI driver fails.
+ * Workaround this by dlopen()'ing libglapi with RTLD_GLOBAL. */
+ dlopen("libglapi.so.0", RTLD_LAZY | RTLD_GLOBAL);
+
ec->gbm = gbm_create_device(ec->drm.fd);
if (!ec->gbm)
return -1;
format = ec->format;
- if (gl_renderer_create(&ec->base, ec->gbm,
- gl_renderer_opaque_attribs, &format) < 0) {
+ if (gl_renderer->create(&ec->base, ec->gbm,
+ gl_renderer->opaque_attribs, &format) < 0) {
gbm_device_destroy(ec->gbm);
return -1;
}
return -1;
}
- if (gl_renderer_output_create(&output->base, output->surface) < 0) {
+ if (gl_renderer->output_create(&output->base, output->surface) < 0) {
weston_log("failed to create gl renderer output state\n");
gbm_surface_destroy(output->surface);
return -1;
int use_gl;
};
+struct gl_renderer_interface *gl_renderer;
+
static const char default_seat[] = "seat0";
static inline struct fbdev_output *
goto out_shadow_surface;
} else {
setenv("HYBRIS_EGLPLATFORM", "wayland", 1);
- if (gl_renderer_output_create(&output->base,
+ if (gl_renderer->output_create(&output->base,
(EGLNativeWindowType)NULL) < 0) {
weston_log("gl_renderer_output_create failed.\n");
goto out_shadow_surface;
output->shadow_buf = NULL;
}
} else {
- gl_renderer_output_destroy(base);
+ gl_renderer->output_destroy(base);
}
/* Remove the output. */
if (pixman_renderer_init(&compositor->base) < 0)
goto out_launcher;
} else {
- if (gl_renderer_create(&compositor->base, EGL_DEFAULT_DISPLAY,
- gl_renderer_opaque_attribs, NULL) < 0) {
+ gl_renderer = weston_load_module("gl-renderer.so",
+ "gl_renderer_interface");
+ if (!gl_renderer) {
+ weston_log("could not load gl renderer\n");
+ goto out_launcher;
+ }
+
+ if (gl_renderer->create(&compositor->base, EGL_DEFAULT_DISPLAY,
+ gl_renderer->opaque_attribs,
+ NULL) < 0) {
weston_log("gl_renderer_create failed.\n");
goto out_launcher;
}
struct wayland_output *output;
};
+struct gl_renderer_interface *gl_renderer;
+
static void
create_border(struct wayland_compositor *c)
{
edges[2] = c->border.top;
edges[3] = c->border.bottom;
- gl_renderer_set_border(&c->base, pixman_image_get_width(image),
+ gl_renderer->set_border(&c->base, pixman_image_get_width(image),
pixman_image_get_height(image),
pixman_image_get_data(image), edges);
{
struct wayland_output *output = (struct wayland_output *) output_base;
- gl_renderer_output_destroy(output_base);
+ gl_renderer->output_destroy(output_base);
wl_egl_window_destroy(output->parent.egl_window);
free(output);
goto cleanup_output;
}
- if (gl_renderer_output_create(&output->base,
+ if (gl_renderer->output_create(&output->base,
output->parent.egl_window) < 0)
goto cleanup_window;
wl_display_dispatch(c->parent.wl_display);
c->base.wl_display = display;
- if (gl_renderer_create(&c->base, c->parent.wl_display,
- gl_renderer_alpha_attribs,
+
+ gl_renderer = weston_load_module("gl-renderer.so",
+ "gl_renderer_interface");
+ if (!gl_renderer)
+ goto err_display;
+
+ if (gl_renderer->create(&c->base, c->parent.wl_display,
+ gl_renderer->alpha_attribs,
NULL) < 0)
goto err_display;
if (wayland_compositor_create_output(c, width, height) < 0)
goto err_gl;
- /* requires gl_renderer_output_state_create called
+ /* requires gl_renderer->output_state_create called
* by wayland_compositor_create_output */
create_border(c);
int32_t scale;
};
+struct gl_renderer_interface *gl_renderer;
+
static struct xkb_keymap *
x11_compositor_get_keymap(struct x11_compositor *c)
{
pixman_renderer_output_destroy(output_base);
x11_output_deinit_shm(compositor, output);
} else
- gl_renderer_output_destroy(output_base);
+ gl_renderer->output_destroy(output_base);
xcb_destroy_window(compositor->conn, output->window);
struct wm_normal_hints normal_hints;
struct wl_event_loop *loop;
int output_width, output_height;
+ int ret;
uint32_t mask = XCB_CW_EVENT_MASK | XCB_CW_CURSOR;
xcb_atom_t atom_list[1];
uint32_t values[2] = {
return NULL;
}
} else {
- if (gl_renderer_output_create(&output->base, (EGLNativeWindowType)output->window) < 0)
+ ret = gl_renderer->output_create(&output->base,
+ (EGLNativeWindowType) output->window);
+ if (ret < 0)
return NULL;
}
return WL_OUTPUT_TRANSFORM_NORMAL;
}
+static int
+init_gl_renderer(struct x11_compositor *c)
+{
+ int ret;
+
+ gl_renderer = weston_load_module("gl-renderer.so",
+ "gl_renderer_interface");
+ if (!gl_renderer)
+ return -1;
+
+ ret = gl_renderer->create(&c->base, (EGLNativeDisplayType) c->dpy,
+ gl_renderer->opaque_attribs, NULL);
+
+ return ret;
+}
static struct weston_compositor *
x11_compositor_create(struct wl_display *display,
int fullscreen,
if (pixman_renderer_init(&c->base) < 0)
goto err_xdisplay;
}
- else {
- if (gl_renderer_create(&c->base, (EGLNativeDisplayType)c->dpy, gl_renderer_opaque_attribs,
- NULL) < 0)
- goto err_xdisplay;
+ else if (init_gl_renderer(c) < 0) {
+ goto err_xdisplay;
}
weston_log("Using %s renderer\n", use_pixman ? "pixman" : "gl");
raise(SIGTRAP);
}
-static void *
-load_module(const char *name, const char *entrypoint)
+WL_EXPORT void *
+weston_load_module(const char *name, const char *entrypoint)
{
char path[PATH_MAX];
void *module, *init;
while (*p) {
end = strchrnul(p, ',');
snprintf(buffer, sizeof buffer, "%.*s", (int) (end - p), p);
- module_init = load_module(buffer, "module_init");
+ module_init = weston_load_module(buffer, "module_init");
if (module_init)
module_init(ec, argc, argv);
p = end;
section = weston_config_get_section(config, "core", NULL, NULL);
weston_config_section_get_string(section, "modules", &modules, "");
- backend_init = load_module(backend, "backend_init");
+ backend_init = weston_load_module(backend, "backend_init");
if (!backend_init)
exit(EXIT_FAILURE);
int32_t scale,
pixman_box32_t rect);
+void *
+weston_load_module(const char *name, const char *entrypoint);
+
#ifdef __cplusplus
}
#endif
#undef MYERRCODE
}
-WL_EXPORT void
+static void
gl_renderer_print_egl_error_state(void)
{
EGLint code;
output->border.right = gr->border.right;
}
-WL_EXPORT void
+static void
gl_renderer_set_border(struct weston_compositor *ec, int32_t width, int32_t height, void *data,
int32_t *edges)
{
static int
gl_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface);
-WL_EXPORT int
+static int
gl_renderer_output_create(struct weston_output *output,
EGLNativeWindowType window)
{
return 0;
}
-WL_EXPORT void
+static void
gl_renderer_output_destroy(struct weston_output *output)
{
struct gl_renderer *gr = get_renderer(output->compositor);
free(go);
}
-WL_EXPORT EGLSurface
+static EGLSurface
gl_renderer_output_surface(struct weston_output *output)
{
return get_output_state(output)->egl_surface;
return -1;
}
-WL_EXPORT const EGLint gl_renderer_opaque_attribs[] = {
+static const EGLint gl_renderer_opaque_attribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_NONE
};
-WL_EXPORT const EGLint gl_renderer_alpha_attribs[] = {
+static const EGLint gl_renderer_alpha_attribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_NONE
};
-WL_EXPORT int
+static int
gl_renderer_create(struct weston_compositor *ec, EGLNativeDisplayType display,
const EGLint *attribs, const EGLint *visual_id)
{
return -1;
}
-WL_EXPORT EGLDisplay
+static EGLDisplay
gl_renderer_display(struct weston_compositor *ec)
{
return get_renderer(ec)->egl_display;
return 0;
}
+
+WL_EXPORT struct gl_renderer_interface gl_renderer_interface = {
+ .opaque_attribs = gl_renderer_opaque_attribs,
+ .alpha_attribs = gl_renderer_alpha_attribs,
+
+ .create = gl_renderer_create,
+ .display = gl_renderer_display,
+ .output_create = gl_renderer_output_create,
+ .output_destroy = gl_renderer_output_destroy,
+ .output_surface = gl_renderer_output_surface,
+ .set_border = gl_renderer_set_border,
+ .print_egl_error_state = gl_renderer_print_egl_error_state
+};
#include <EGL/egl.h>
-extern const EGLint gl_renderer_opaque_attribs[];
-extern const EGLint gl_renderer_alpha_attribs[];
-
-int
-gl_renderer_create(struct weston_compositor *ec, EGLNativeDisplayType display,
- const EGLint *attribs, const EGLint *visual_id);
-EGLDisplay
-gl_renderer_display(struct weston_compositor *ec);
-int
-gl_renderer_output_create(struct weston_output *output,
- EGLNativeWindowType window);
-void
-gl_renderer_output_destroy(struct weston_output *output);
-EGLSurface
-gl_renderer_output_surface(struct weston_output *output);
-void
-gl_renderer_set_border(struct weston_compositor *ec, int32_t width, int32_t height, void *data,
- int32_t *edges);
-
-void
-gl_renderer_print_egl_error_state(void);
#else
typedef int EGLint;
typedef intptr_t EGLNativeWindowType;
#define EGL_DEFAULT_DISPLAY NULL
-static const EGLint gl_renderer_opaque_attribs[];
-static const EGLint gl_renderer_alpha_attribs[];
-
-inline static int
-gl_renderer_create(struct weston_compositor *ec, EGLNativeDisplayType display,
- const EGLint *attribs, const EGLint *visual_id)
-{
- return -1;
-}
-
-inline static EGLDisplay
-gl_renderer_display(struct weston_compositor *ec)
-{
- return 0;
-}
-
-inline static int
-gl_renderer_output_create(struct weston_output *output,
- EGLNativeWindowType window)
-{
- return -1;
-}
-
-inline static void
-gl_renderer_output_destroy(struct weston_output *output)
-{
-}
-
-inline static EGLSurface
-gl_renderer_output_surface(struct weston_output *output)
-{
- return 0;
-}
-
-inline static void
-gl_renderer_set_border(struct weston_compositor *ec, int32_t width, int32_t height, void *data,
- int32_t *edges)
-{
-}
-
-inline static void
-gl_renderer_print_egl_error_state(void)
-{
-}
-
#endif
+
+struct gl_renderer_interface {
+ const EGLint *opaque_attribs;
+ const EGLint *alpha_attribs;
+
+ int (*create)(struct weston_compositor *ec,
+ EGLNativeDisplayType display,
+ const EGLint *attribs,
+ const EGLint *visual_id);
+
+ EGLDisplay (*display)(struct weston_compositor *ec);
+
+ int (*output_create)(struct weston_output *output,
+ EGLNativeWindowType window);
+
+ void (*output_destroy)(struct weston_output *output);
+
+ EGLSurface (*output_surface)(struct weston_output *output);
+
+ void (*set_border)(struct weston_compositor *ec,
+ int32_t width, int32_t height,
+ void *data, int32_t *edges);
+
+ void (*print_egl_error_state)(void);
+};
+
+struct gl_renderer_interface gl_renderer_interface;