On Mon, Oct 14, 2013 at 03:57:11PM +0300, Ander Conselvan de Oliveira wrote: > The time spent loading EGL and GLES libraries from disk can be a > considerable hit in some embedded use cases. If Weston is compiled > with EGL support, the binary will depend on those libraries, even if > a software renderer is in use. > > This patch splits the GL renderer into a separate loadable module, > and moves the dependency on EGL and GLES to it. The backends still > need the EGL headers for the native types and EGLint. The function > load_module() is renamed to weston_load_module() and exported, so > that it can be used by the backends. > > The gl renderer interface is changed so that there is only one symbol > that needs to be dlsym()'d. This symbol contains pointers to all the > functions and data necessary to interact with the renderer. As a side > effect, this change simplifies gl-renderer.h a great deal.
Thanks, looks good now, pushed. Kristian > --- > configure.ac | 2 +- > src/Makefile.am | 28 ++++++++++----- > src/compositor-drm.c | 27 ++++++++++---- > src/compositor-fbdev.c | 18 +++++++--- > src/compositor-wayland.c | 20 +++++++---- > src/compositor-x11.c | 30 ++++++++++++---- > src/compositor.c | 8 ++--- > src/compositor.h | 3 ++ > src/gl-renderer.c | 31 +++++++++++----- > src/gl-renderer.h | 93 > ++++++++++++++---------------------------------- > 10 files changed, 150 insertions(+), 110 deletions(-) > > diff --git a/configure.ac b/configure.ac > index 234f098..9500128 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -62,7 +62,7 @@ AC_ARG_ENABLE(egl, [ --disable-egl],, > 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, > diff --git a/src/Makefile.am b/src/Makefile.am > index 749c074..b0eae7c 100644 > --- a/src/Makefile.am > +++ b/src/Makefile.am > @@ -40,7 +40,6 @@ weston_SOURCES = \ > subsurface-server-protocol.h \ > bindings.c \ > animation.c \ > - gl-renderer.h \ > noop-renderer.c \ > pixman-renderer.c \ > pixman-renderer.h \ > @@ -50,13 +49,6 @@ weston_SOURCES = \ > 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 $@; \ > @@ -104,6 +96,7 @@ module_LTLIBRARIES = \ > $(tablet_shell) \ > $(cms_static) \ > $(cms_colord) \ > + $(gl_renderer) \ > $(x11_backend) \ > $(drm_backend) \ > $(wayland_backend) \ > @@ -119,6 +112,21 @@ else > 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 > @@ -126,6 +134,7 @@ x11_backend_la_LIBADD = $(COMPOSITOR_LIBS) > $(X11_COMPOSITOR_LIBS) \ > ../shared/libshared-cairo.la > x11_backend_la_CFLAGS = \ > $(COMPOSITOR_CFLAGS) \ > + $(EGL_CFLAGS) \ > $(PIXMAN_CFLAGS) \ > $(CAIRO_CFLAGS) \ > $(X11_COMPOSITOR_CFLAGS) \ > @@ -140,6 +149,7 @@ drm_backend_la_LIBADD = $(COMPOSITOR_LIBS) > $(DRM_COMPOSITOR_LIBS) \ > ../shared/libshared.la -lrt > drm_backend_la_CFLAGS = \ > $(COMPOSITOR_CFLAGS) \ > + $(EGL_CFLAGS) \ > $(DRM_COMPOSITOR_CFLAGS) \ > $(GCC_CFLAGS) > drm_backend_la_SOURCES = \ > @@ -168,6 +178,7 @@ wayland_backend_la_LIBADD = $(COMPOSITOR_LIBS) > $(WAYLAND_COMPOSITOR_LIBS) \ > ../shared/libshared-cairo.la > wayland_backend_la_CFLAGS = \ > $(COMPOSITOR_CFLAGS) \ > + $(EGL_CFLAGS) \ > $(PIXMAN_CFLAGS) \ > $(CAIRO_CFLAGS) \ > $(WAYLAND_COMPOSITOR_CFLAGS) \ > @@ -219,6 +230,7 @@ fbdev_backend_la_LIBADD = \ > ../shared/libshared.la > fbdev_backend_la_CFLAGS = \ > $(COMPOSITOR_CFLAGS) \ > + $(EGL_CFLAGS) \ > $(FBDEV_COMPOSITOR_CFLAGS) \ > $(PIXMAN_CFLAGS) \ > $(GCC_CFLAGS) > diff --git a/src/compositor-drm.c b/src/compositor-drm.c > index 0ac5efa..0a02962 100644 > --- a/src/compositor-drm.c > +++ b/src/compositor-drm.c > @@ -33,6 +33,7 @@ > #include <linux/vt.h> > #include <assert.h> > #include <sys/mman.h> > +#include <dlfcn.h> > #include <time.h> > > #include <xf86drm.h> > @@ -193,6 +194,8 @@ struct drm_sprite { > uint32_t formats[]; > }; > > +static struct gl_renderer_interface *gl_renderer; > + > static const char default_seat[] = "seat0"; > > static void > @@ -1083,7 +1086,7 @@ drm_output_destroy(struct weston_output *output_base) > 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); > } > > @@ -1174,7 +1177,7 @@ drm_output_switch_mode(struct weston_output > *output_base, struct weston_mode *mo > 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) { > @@ -1242,14 +1245,26 @@ init_drm(struct drm_compositor *ec, struct > udev_device *device) > static int > init_egl(struct drm_compositor *ec) > { > + 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; > > - if (gl_renderer_create(&ec->base, ec->gbm, > - gl_renderer_opaque_attribs, > - &ec->format) < 0) { > + if (gl_renderer->create(&ec->base, ec->gbm, > + gl_renderer->opaque_attribs, > + &ec->format) < 0) { > gbm_device_destroy(ec->gbm); > return -1; > } > @@ -1451,7 +1466,7 @@ drm_output_init_egl(struct drm_output *output, struct > drm_compositor *ec) > 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; > diff --git a/src/compositor-fbdev.c b/src/compositor-fbdev.c > index 3d2819b..002ce0b 100644 > --- a/src/compositor-fbdev.c > +++ b/src/compositor-fbdev.c > @@ -95,6 +95,8 @@ struct fbdev_parameters { > int use_gl; > }; > > +struct gl_renderer_interface *gl_renderer; > + > static const char default_seat[] = "seat0"; > > static inline struct fbdev_output * > @@ -623,7 +625,7 @@ fbdev_output_create(struct fbdev_compositor *compositor, > 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; > @@ -684,7 +686,7 @@ fbdev_output_destroy(struct weston_output *base) > output->shadow_buf = NULL; > } > } else { > - gl_renderer_output_destroy(base); > + gl_renderer->output_destroy(base); > } > > /* Remove the output. */ > @@ -923,8 +925,16 @@ fbdev_compositor_create(struct wl_display *display, int > *argc, char *argv[], > 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; > } > diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c > index 77b2a2c..7b670d9 100644 > --- a/src/compositor-wayland.c > +++ b/src/compositor-wayland.c > @@ -89,6 +89,8 @@ struct wayland_input { > struct wayland_output *output; > }; > > +struct gl_renderer_interface *gl_renderer; > + > static void > create_border(struct wayland_compositor *c) > { > @@ -106,7 +108,7 @@ 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); > > @@ -233,7 +235,7 @@ wayland_output_destroy(struct weston_output *output_base) > { > 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); > @@ -283,7 +285,7 @@ wayland_compositor_create_output(struct > wayland_compositor *c, > 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; > > @@ -742,8 +744,14 @@ wayland_compositor_create(struct wl_display *display, > 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; > > @@ -759,7 +767,7 @@ wayland_compositor_create(struct wl_display *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); > > diff --git a/src/compositor-x11.c b/src/compositor-x11.c > index 704e751..44e92ba 100644 > --- a/src/compositor-x11.c > +++ b/src/compositor-x11.c > @@ -115,6 +115,8 @@ struct x11_output { > int32_t scale; > }; > > +struct gl_renderer_interface *gl_renderer; > + > static struct xkb_keymap * > x11_compositor_get_keymap(struct x11_compositor *c) > { > @@ -519,7 +521,7 @@ x11_output_destroy(struct weston_output *output_base) > 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); > > @@ -785,6 +787,7 @@ x11_compositor_create_output(struct x11_compositor *c, > int x, int y, > 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] = { > @@ -905,7 +908,9 @@ x11_compositor_create_output(struct x11_compositor *c, > int x, int y, > 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; > } > > @@ -1441,6 +1446,21 @@ parse_transform(const char *transform, const char > *output_name) > 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, > @@ -1497,10 +1517,8 @@ x11_compositor_create(struct wl_display *display, > 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"); > > diff --git a/src/compositor.c b/src/compositor.c > index 376ddfd..04e192b 100644 > --- a/src/compositor.c > +++ b/src/compositor.c > @@ -3222,8 +3222,8 @@ on_caught_signal(int s, siginfo_t *siginfo, void > *context) > 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; > @@ -3273,7 +3273,7 @@ load_modules(struct weston_compositor *ec, const char > *modules, > 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; > @@ -3507,7 +3507,7 @@ int main(int argc, char *argv[]) > 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); > > diff --git a/src/compositor.h b/src/compositor.h > index a19d966..e2c53a0 100644 > --- a/src/compositor.h > +++ b/src/compositor.h > @@ -1241,6 +1241,9 @@ weston_transformed_rect(int width, int height, > int32_t scale, > pixman_box32_t rect); > > +void * > +weston_load_module(const char *name, const char *entrypoint); > + > #ifdef __cplusplus > } > #endif > diff --git a/src/gl-renderer.c b/src/gl-renderer.c > index ae69f22..f02445b 100644 > --- a/src/gl-renderer.c > +++ b/src/gl-renderer.c > @@ -170,7 +170,7 @@ egl_error_string(EGLint code) > #undef MYERRCODE > } > > -WL_EXPORT void > +static void > gl_renderer_print_egl_error_state(void) > { > EGLint code; > @@ -1440,7 +1440,7 @@ output_apply_border(struct weston_output *output, > struct gl_renderer *gr) > 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) > { > @@ -1475,7 +1475,7 @@ gl_renderer_set_border(struct weston_compositor *ec, > int32_t width, int32_t heig > 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) > { > @@ -1514,7 +1514,7 @@ gl_renderer_output_create(struct weston_output *output, > return 0; > } > > -WL_EXPORT void > +static void > gl_renderer_output_destroy(struct weston_output *output) > { > struct gl_renderer *gr = get_renderer(output->compositor); > @@ -1529,7 +1529,7 @@ gl_renderer_output_destroy(struct weston_output *output) > free(go); > } > > -WL_EXPORT EGLSurface > +static EGLSurface > gl_renderer_output_surface(struct weston_output *output) > { > return get_output_state(output)->egl_surface; > @@ -1602,7 +1602,7 @@ out: > 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, > @@ -1612,7 +1612,7 @@ WL_EXPORT const EGLint gl_renderer_opaque_attribs[] = { > 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, > @@ -1622,7 +1622,7 @@ WL_EXPORT const EGLint gl_renderer_alpha_attribs[] = { > EGL_NONE > }; > > -WL_EXPORT int > +static int > gl_renderer_create(struct weston_compositor *ec, EGLNativeDisplayType > display, > const EGLint *attribs, const EGLint *visual_id) > { > @@ -1673,7 +1673,7 @@ err_egl: > return -1; > } > > -WL_EXPORT EGLDisplay > +static EGLDisplay > gl_renderer_display(struct weston_compositor *ec) > { > return get_renderer(ec)->egl_display; > @@ -1863,3 +1863,16 @@ gl_renderer_setup(struct weston_compositor *ec, > EGLSurface egl_surface) > > 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 > +}; > diff --git a/src/gl-renderer.h b/src/gl-renderer.h > index 4919a1e..1656491 100644 > --- a/src/gl-renderer.h > +++ b/src/gl-renderer.h > @@ -28,27 +28,6 @@ > > #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; > @@ -57,49 +36,31 @@ typedef void *EGLSurface; > typedef intptr_t EGLNativeDisplayType; > typedef intptr_t EGLNativeWindowType; > > -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; > -- > 1.8.1.2 > > _______________________________________________ > wayland-devel mailing list > wayland-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/wayland-devel _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel