This provides an new API for gles2-renderer. It allows to move most EGL initialization code and EGL surface creation into gles2-renderer, which makes compositor backends less dependent on gles2-renderer. As a side effect weston_output gets a per-renderer state which gles2-renderer uses to store the EGL surface.
--- src/compositor-android.c | 72 +++++++---------- src/compositor-drm.c | 87 ++++++--------------- src/compositor-wayland.c | 58 +++----------- src/compositor-x11.c | 71 +++-------------- src/compositor.h | 23 +++++- src/gles2-renderer.c | 197 ++++++++++++++++++++++++++++++++++++++++++----- 6 files changed, 265 insertions(+), 243 deletions(-) diff --git a/src/compositor-android.c b/src/compositor-android.c index 3c0273a..bf14910 100644 --- a/src/compositor-android.c +++ b/src/compositor-android.c @@ -145,6 +145,8 @@ android_output_destroy(struct weston_output *base) wl_list_remove(&output->base.link); weston_output_destroy(&output->base); + gles2_renderer_output_unbind(base); + android_framebuffer_destroy(output->fb); free(output); @@ -319,6 +321,8 @@ android_seat_create(struct android_compositor *compositor) static int android_egl_choose_config(struct android_compositor *compositor, struct android_framebuffer *fb, + EGLDisplay egl_display, + EGLConfig *egl_config, const EGLint *attribs) { EGLBoolean ret; @@ -332,9 +336,9 @@ android_egl_choose_config(struct android_compositor *compositor, * surfaceflinger/DisplayHardware/DisplayHardware.cpp */ - compositor->base.egl_config = NULL; + *egl_config = NULL; - ret = eglGetConfigs(compositor->base.egl_display, NULL, 0, &count); + ret = eglGetConfigs(egl_display, NULL, 0, &count); if (ret == EGL_FALSE || count < 1) return -1; @@ -342,27 +346,27 @@ android_egl_choose_config(struct android_compositor *compositor, if (!configs) return -1; - ret = eglChooseConfig(compositor->base.egl_display, attribs, configs, + ret = eglChooseConfig(egl_display, attribs, configs, count, &matched); if (ret == EGL_FALSE || matched < 1) goto out; for (i = 0; i < matched; ++i) { EGLint id; - ret = eglGetConfigAttrib(compositor->base.egl_display, + ret = eglGetConfigAttrib(egl_display, configs[i], EGL_NATIVE_VISUAL_ID, &id); if (ret == EGL_FALSE) continue; if (id > 0 && fb->format == id) { - compositor->base.egl_config = configs[i]; + *egl_config = configs[i]; break; } } out: free(configs); - if (!compositor->base.egl_config) + if (!*egl_config) return -1; return 0; @@ -372,7 +376,8 @@ static int android_init_egl(struct android_compositor *compositor, struct android_output *output) { - EGLint eglmajor, eglminor; + EGLDisplay egl_display; + EGLConfig egl_config; int ret; static const EGLint config_attrs[] = { @@ -385,66 +390,41 @@ android_init_egl(struct android_compositor *compositor, EGL_NONE }; - compositor->base.egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); - if (compositor->base.egl_display == EGL_NO_DISPLAY) { - weston_log("Failed to create EGL display.\n"); - print_egl_error_state(); - return -1; - } + egl_display = gles2_renderer_init_without_config(&compositor->base, EGL_DEFAULT_DISPLAY); - ret = eglInitialize(compositor->base.egl_display, &eglmajor, &eglminor); - if (!ret) { - weston_log("Failed to initialise EGL.\n"); + if (egl_display == EGL_NO_DISPLAY) { + weston_log("Failed to create EGL display.\n"); print_egl_error_state(); return -1; } - ret = android_egl_choose_config(compositor, output->fb, config_attrs); + ret = android_egl_choose_config(compositor, output->fb, egl_display, &egl_config, config_attrs); if (ret < 0) { weston_log("Failed to find an EGL config.\n"); print_egl_error_state(); return -1; } - output->base.egl_surface = - eglCreateWindowSurface(compositor->base.egl_display, - compositor->base.egl_config, - output->fb->native_window, - NULL); - if (output->base.egl_surface == EGL_NO_SURFACE) { - weston_log("Failed to create FB EGLSurface.\n"); - print_egl_error_state(); + gles2_renderer_select_config(&compositor->base, egl_config); + + if (gles2_renderer_output_state_create_and_bind(&output->base, output->fb->native_window) < 0) return -1; - } return 0; } static void -android_fini_egl(struct android_compositor *compositor) -{ - gles2_renderer_destroy(&compositor->base); - - eglMakeCurrent(compositor->base.egl_display, - EGL_NO_SURFACE, EGL_NO_SURFACE, - EGL_NO_CONTEXT); - - eglTerminate(compositor->base.egl_display); - eglReleaseThread(); -} - -static void android_compositor_destroy(struct weston_compositor *base) { struct android_compositor *compositor = to_android_compositor(base); android_seat_destroy(compositor->seat); + gles2_renderer_destroy(base); + /* destroys outputs, too */ weston_compositor_shutdown(&compositor->base); - android_fini_egl(compositor); - free(compositor); } @@ -478,17 +458,17 @@ android_compositor_create(struct wl_display *display, int argc, char *argv[], android_compositor_add_output(compositor, output); - if (gles2_renderer_init(&compositor->base) < 0) - goto err_egl; + if (gles2_renderer_outputs_ready(&compositor->base) < 0) + goto err_gles2; compositor->seat = android_seat_create(compositor); if (!compositor->seat) - goto err_egl; + goto err_gles2; return &compositor->base; -err_egl: - android_fini_egl(compositor); +err_gles2: + gles2_renderer_destroy(&compositor->base); err_output: android_output_destroy(&output->base); err_compositor: diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 3e75387..96a206e 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -861,7 +861,7 @@ drm_output_destroy(struct weston_output *output_base) c->crtc_allocator &= ~(1 << output->crtc_id); c->connector_allocator &= ~(1 << output->connector_id); - eglDestroySurface(c->base.egl_display, output->base.egl_surface); + gles2_renderer_output_unbind(output_base); gbm_surface_destroy(output->surface); weston_plane_release(&output->fb_plane); @@ -907,7 +907,7 @@ drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo int ret; struct drm_compositor *ec; struct gbm_surface *surface; - EGLSurface egl_surface; + struct gles2_output_state *state; if (output_base == NULL) { weston_log("output is NULL.\n"); @@ -967,15 +967,10 @@ drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo return -1; } - egl_surface = - eglCreateWindowSurface(ec->base.egl_display, - ec->base.egl_config, - surface, NULL); + state = gles2_renderer_output_state_create(&ec->base, surface); - if (egl_surface == EGL_NO_SURFACE) { - weston_log("failed to create egl surface\n"); - goto err; - } + if (!state) + goto err_gbm; ret = drmModeSetCrtc(ec->drm.fd, output->crtc_id, @@ -983,7 +978,7 @@ drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo &output->connector_id, 1, &drm_mode->mode_info); if (ret) { weston_log("failed to set mode\n"); - goto err; + goto err_gles2; } /* reset rendering stuff. */ @@ -1005,10 +1000,10 @@ drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo } output->next = NULL; - eglDestroySurface(ec->base.egl_display, output->base.egl_surface); + gles2_renderer_output_unbind(output_base); gbm_surface_destroy(output->surface); - output->base.egl_surface = egl_surface; output->surface = surface; + gles2_renderer_output_bind(&output->base, state); /*update output*/ output->base.current = &drm_mode->base; @@ -1016,8 +1011,9 @@ drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo weston_output_move(&output->base, output->base.x, output->base.y); return 0; -err: - eglDestroySurface(ec->base.egl_display, egl_surface); +err_gles2: + gles2_renderer_output_state_destroy(&ec->base, state); +err_gbm: gbm_surface_destroy(surface); return -1; } @@ -1039,18 +1035,8 @@ on_drm_input(int fd, uint32_t mask, void *data) static int init_egl(struct drm_compositor *ec, struct udev_device *device) { - EGLint major, minor, n; const char *filename, *sysnum; int fd; - static const EGLint config_attribs[] = { - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_RED_SIZE, 1, - EGL_GREEN_SIZE, 1, - EGL_BLUE_SIZE, 1, - EGL_ALPHA_SIZE, 0, - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL_NONE - }; sysnum = udev_device_get_sysnum(device); if (sysnum) @@ -1073,22 +1059,9 @@ init_egl(struct drm_compositor *ec, struct udev_device *device) ec->drm.fd = fd; ec->gbm = gbm_create_device(ec->drm.fd); - ec->base.egl_display = eglGetDisplay(ec->gbm); - if (ec->base.egl_display == NULL) { - weston_log("failed to create display\n"); - return -1; - } - - if (!eglInitialize(ec->base.egl_display, &major, &minor)) { - weston_log("failed to initialize display\n"); - return -1; - } - if (!eglChooseConfig(ec->base.egl_display, config_attribs, - &ec->base.egl_config, 1, &n) || n != 1) { - weston_log("failed to choose config: %d\n", n); + if (gles2_renderer_init(&ec->base, ec->gbm, 0) < 0) return -1; - } return 0; } @@ -1445,15 +1418,13 @@ create_output_for_connector(struct drm_compositor *ec, goto err_free; } - output->base.egl_surface = - eglCreateWindowSurface(ec->base.egl_display, - ec->base.egl_config, - output->surface, - NULL); - if (output->base.egl_surface == EGL_NO_SURFACE) { - weston_log("failed to create egl surface\n"); - goto err_surface; - } + weston_output_init(&output->base, &ec->base, x, y, + connector->mmWidth, connector->mmHeight, + o ? o->transform : WL_OUTPUT_TRANSFORM_NORMAL); + + /* this requires output->base.compositor to be initialized */ + if (gles2_renderer_output_state_create_and_bind(&output->base, output->surface) < 0) + goto err_output; output->cursor_bo[0] = gbm_bo_create(ec->gbm, 64, 64, GBM_FORMAT_ARGB8888, @@ -1473,10 +1444,6 @@ create_output_for_connector(struct drm_compositor *ec, output->base.backlight_current = drm_get_backlight(output); } - weston_output_init(&output->base, &ec->base, x, y, - connector->mmWidth, connector->mmHeight, - o ? o->transform : WL_OUTPUT_TRANSFORM_NORMAL); - wl_list_insert(ec->base.output_list.prev, &output->base.link); output->base.origin = output->base.current; @@ -1503,7 +1470,8 @@ create_output_for_connector(struct drm_compositor *ec, return 0; -err_surface: +err_output: + weston_output_destroy(&output->base); gbm_surface_destroy(output->surface); err_free: wl_list_for_each_safe(drm_mode, next, &output->base.mode_list, @@ -2039,12 +2007,6 @@ drm_destroy(struct weston_compositor *ec) gles2_renderer_destroy(ec); - /* Work around crash in egl_dri2.c's dri2_make_current() */ - eglMakeCurrent(ec->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, - EGL_NO_CONTEXT); - eglTerminate(ec->egl_display); - eglReleaseThread(); - gbm_device_destroy(d->gbm); destroy_sprites(d); if (weston_launcher_drm_set_master(&d->base, d->drm.fd, 0) < 0) @@ -2238,7 +2200,7 @@ drm_compositor_create(struct wl_display *display, goto err_sprite; } - if (gles2_renderer_init(&ec->base) < 0) + if (gles2_renderer_outputs_ready(&ec->base) < 0) goto err_egl; path = NULL; @@ -2280,10 +2242,7 @@ err_drm_source: wl_list_for_each_safe(weston_seat, next, &ec->base.seat_list, link) evdev_input_destroy(weston_seat); err_egl: - eglMakeCurrent(ec->base.egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, - EGL_NO_CONTEXT); - eglTerminate(ec->base.egl_display); - eglReleaseThread(); + gles2_renderer_destroy(&ec->base); gbm_device_destroy(ec->gbm); err_sprite: destroy_sprites(ec); diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c index 56759fc..1e60d0f 100644 --- a/src/compositor-wayland.c +++ b/src/compositor-wayland.c @@ -241,41 +241,6 @@ create_border(struct wayland_compositor *c) pixman_image_unref(image); } -static int -wayland_compositor_init_egl(struct wayland_compositor *c) -{ - EGLint major, minor; - EGLint n; - EGLint config_attribs[] = { - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_RED_SIZE, 1, - EGL_GREEN_SIZE, 1, - EGL_BLUE_SIZE, 1, - EGL_ALPHA_SIZE, 1, - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL_NONE - }; - - c->base.egl_display = eglGetDisplay(c->parent.wl_display); - if (c->base.egl_display == NULL) { - weston_log("failed to create display\n"); - return -1; - } - - if (!eglInitialize(c->base.egl_display, &major, &minor)) { - weston_log("failed to initialize display\n"); - return -1; - } - - if (!eglChooseConfig(c->base.egl_display, config_attribs, - &c->base.egl_config, 1, &n) || n == 0) { - weston_log("failed to choose config: %d\n", n); - return -1; - } - - return 0; -} - static void frame_done(void *data, struct wl_callback *callback, uint32_t time) { @@ -317,9 +282,9 @@ static void wayland_output_destroy(struct weston_output *output_base) { struct wayland_output *output = (struct wayland_output *) output_base; - struct weston_compositor *ec = output->base.compositor; - eglDestroySurface(ec->egl_display, output->base.egl_surface); + gles2_renderer_output_unbind(output_base); + wl_egl_window_destroy(output->parent.egl_window); free(output); @@ -373,13 +338,8 @@ wayland_compositor_create_output(struct wayland_compositor *c, goto cleanup_output; } - output->base.egl_surface = - eglCreateWindowSurface(c->base.egl_display, c->base.egl_config, - output->parent.egl_window, NULL); - if (!output->base.egl_surface) { - weston_log("failed to create window surface\n"); + if (gles2_renderer_output_state_create_and_bind(&output->base, output->parent.egl_window) < 0) goto cleanup_window; - } output->parent.shell_surface = wl_shell_get_shell_surface(c->parent.shell, @@ -831,7 +791,7 @@ wayland_compositor_create(struct wl_display *display, wl_display_dispatch(c->parent.wl_display); c->base.wl_display = display; - if (wayland_compositor_init_egl(c) < 0) + if (gles2_renderer_init(&c->base, c->parent.wl_display, 1) < 0) goto err_display; c->base.destroy = wayland_destroy; @@ -844,11 +804,11 @@ wayland_compositor_create(struct wl_display *display, /* requires border fields */ if (wayland_compositor_create_output(c, width, height) < 0) - goto err_display; + goto err_gles2; /* requires wayland_compositor_create_output */ - if (gles2_renderer_init(&c->base) < 0) - goto err_display; + if (gles2_renderer_outputs_ready(&c->base) < 0) + goto err_gles2; /* requires gles2_renderer_init */ create_border(c); @@ -860,12 +820,14 @@ wayland_compositor_create(struct wl_display *display, wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE, wayland_compositor_handle_event, c); if (c->parent.wl_source == NULL) - goto err_display; + goto err_gles2; wl_event_source_check(c->parent.wl_source); return &c->base; +err_gles2: + gles2_renderer_destroy(&c->base); err_display: wl_display_disconnect(c->parent.wl_display); err_compositor: diff --git a/src/compositor-x11.c b/src/compositor-x11.c index e616f45..80c28b0 100644 --- a/src/compositor-x11.c +++ b/src/compositor-x11.c @@ -239,53 +239,6 @@ x11_input_destroy(struct x11_compositor *compositor) weston_seat_release(&compositor->core_seat); } -static int -x11_compositor_init_egl(struct x11_compositor *c) -{ - EGLint major, minor; - EGLint n; - EGLint config_attribs[] = { - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_RED_SIZE, 1, - EGL_GREEN_SIZE, 1, - EGL_BLUE_SIZE, 1, - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL_NONE - }; - - c->base.egl_display = eglGetDisplay(c->dpy); - if (c->base.egl_display == NULL) { - weston_log("failed to create display\n"); - return -1; - } - - if (!eglInitialize(c->base.egl_display, &major, &minor)) { - weston_log("failed to initialize display\n"); - return -1; - } - - if (!eglChooseConfig(c->base.egl_display, config_attribs, - &c->base.egl_config, 1, &n) || n == 0) { - weston_log("failed to choose config: %d\n", n); - return -1; - } - - return 0; -} - -static void -x11_compositor_fini_egl(struct x11_compositor *compositor) -{ - gles2_renderer_destroy(&compositor->base); - - eglMakeCurrent(compositor->base.egl_display, - EGL_NO_SURFACE, EGL_NO_SURFACE, - EGL_NO_CONTEXT); - - eglTerminate(compositor->base.egl_display); - eglReleaseThread(); -} - static void x11_output_repaint(struct weston_output *output_base, pixman_region32_t *damage) @@ -322,8 +275,7 @@ x11_output_destroy(struct weston_output *output_base) wl_list_remove(&output->base.link); wl_event_source_remove(output->finish_frame_timer); - eglDestroySurface(compositor->base.egl_display, - output->base.egl_surface); + gles2_renderer_output_unbind(output_base); xcb_destroy_window(compositor->conn, output->window); @@ -529,13 +481,8 @@ x11_compositor_create_output(struct x11_compositor *c, int x, int y, x11_output_change_state(output, 1, c->atom.net_wm_state_fullscreen); - output->base.egl_surface = - eglCreateWindowSurface(c->base.egl_display, c->base.egl_config, - output->window, NULL); - if (!output->base.egl_surface) { - weston_log("failed to create window surface\n"); + if (gles2_renderer_output_state_create_and_bind(&output->base, output->window) < 0) return NULL; - } loop = wl_display_get_event_loop(c->base.wl_display); output->finish_frame_timer = @@ -1085,7 +1032,7 @@ x11_destroy(struct weston_compositor *ec) weston_compositor_shutdown(ec); /* destroys outputs, too */ - x11_compositor_fini_egl(compositor); + gles2_renderer_destroy(ec); XCloseDisplay(compositor->dpy); free(ec); @@ -1133,14 +1080,14 @@ x11_compositor_create(struct wl_display *display, x11_compositor_get_resources(c); c->base.wl_display = display; - if (x11_compositor_init_egl(c) < 0) + if (gles2_renderer_init(&c->base, c->dpy, 0) < 0) goto err_xdisplay; c->base.destroy = x11_destroy; c->base.restore = x11_restore; if (x11_input_create(c, no_input) < 0) - goto err_egl; + goto err_gles2; width = option_width ? option_width : 1024; height = option_height ? option_height : 640; @@ -1173,8 +1120,8 @@ x11_compositor_create(struct wl_display *display, x = pixman_region32_extents(&output->base.region)->x2; } - if (gles2_renderer_init(&c->base) < 0) - goto err_egl; + if (gles2_renderer_outputs_ready(&c->base) < 0) + goto err_x11_input; c->xcb_source = wl_event_loop_add_fd(c->base.input_loop, @@ -1187,8 +1134,8 @@ x11_compositor_create(struct wl_display *display, err_x11_input: x11_input_destroy(c); -err_egl: - x11_compositor_fini_egl(c); +err_gles2: + gles2_renderer_destroy(&c->base); err_xdisplay: XCloseDisplay(c->dpy); err_free: diff --git a/src/compositor.h b/src/compositor.h index 3176bfd..59eb4bf 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -154,7 +154,8 @@ enum dpms_enum { struct weston_output { uint32_t id; - EGLSurface egl_surface; + void *renderer_state; + struct wl_list link; struct wl_list resource_list; struct wl_global *global; @@ -822,8 +823,26 @@ weston_surface_destroy(struct weston_surface *surface); int weston_output_switch_mode(struct weston_output *output, struct weston_mode *mode); +struct gles2_output_state; + +int +gles2_renderer_init(struct weston_compositor *ec, EGLNativeDisplayType display, int alpha); +EGLDisplay +gles2_renderer_init_without_config(struct weston_compositor *ec, EGLNativeDisplayType display); +void +gles2_renderer_select_config(struct weston_compositor *ec, EGLConfig config); int -gles2_renderer_init(struct weston_compositor *ec); +gles2_renderer_outputs_ready(struct weston_compositor *ec); +int +gles2_renderer_output_state_create_and_bind(struct weston_output *output, EGLNativeWindowType window); +struct gles2_output_state * +gles2_renderer_output_state_create(struct weston_compositor *ec, EGLNativeWindowType window); +void +gles2_renderer_output_state_destroy(struct weston_compositor *ec, struct gles2_output_state *state); +void +gles2_renderer_output_bind(struct weston_output *output, struct gles2_output_state *state); +void +gles2_renderer_output_unbind(struct weston_output *output); void gles2_renderer_destroy(struct weston_compositor *ec); diff --git a/src/gles2-renderer.c b/src/gles2-renderer.c index 544cc15..a03a7dd 100644 --- a/src/gles2-renderer.c +++ b/src/gles2-renderer.c @@ -30,6 +30,26 @@ #include "compositor.h" +struct gles2_output_state { + EGLSurface egl_surface; +}; + +struct gles2_renderer { + struct weston_renderer base; +}; + +static inline struct gles2_output_state * +get_output_state(struct weston_output *output) +{ + return (struct gles2_output_state *)output->renderer_state; +} + +static inline struct gles2_renderer * +get_renderer(struct weston_compositor *ec) +{ + return (struct gles2_renderer *)ec->renderer; +} + static const char * egl_error_string(EGLint code) { @@ -700,6 +720,7 @@ static void gles2_renderer_repaint_output(struct weston_output *output, pixman_region32_t *output_damage) { + struct gles2_output_state *output_state = get_output_state(output); struct weston_compositor *compositor = output->compositor; EGLBoolean ret; static int errored; @@ -712,8 +733,8 @@ gles2_renderer_repaint_output(struct weston_output *output, glViewport(0, 0, width, height); - ret = eglMakeCurrent(compositor->egl_display, output->egl_surface, - output->egl_surface, compositor->egl_context); + ret = eglMakeCurrent(compositor->egl_display, output_state->egl_surface, + output_state->egl_surface, compositor->egl_context); if (ret == EGL_FALSE) { if (errored) return; @@ -749,7 +770,7 @@ gles2_renderer_repaint_output(struct weston_output *output, wl_signal_emit(&output->frame_signal, output); - ret = eglSwapBuffers(compositor->egl_display, output->egl_surface); + ret = eglSwapBuffers(compositor->egl_display, output_state->egl_surface); if (ret == EGL_FALSE && !errored) { errored = 1; weston_log("Failed in eglSwapBuffers.\n"); @@ -1157,24 +1178,167 @@ log_egl_config_info(EGLDisplay egldpy, EGLConfig eglconfig) weston_log_continue(" unknown\n"); } -struct gles2_renderer { - struct weston_renderer base; -}; +static int +create_renderer(struct weston_compositor *ec) +{ + struct gles2_renderer *renderer = malloc(sizeof *renderer); + + if (renderer == NULL) + return -1; + + renderer->base.repaint_output = gles2_renderer_repaint_output; + renderer->base.flush_damage = gles2_renderer_flush_damage; + renderer->base.attach = gles2_renderer_attach; + renderer->base.destroy_surface = gles2_renderer_destroy_surface; + + ec->renderer = &renderer->base; + + return 0; +} + +static int +init_display(struct weston_compositor *ec, EGLNativeDisplayType display) +{ + EGLint major, minor; + + if (create_renderer(ec) < 0) + return -1; + + ec->egl_display = eglGetDisplay(display); + if (ec->egl_display == NULL) { + weston_log("failed to create display\n"); + print_egl_error_state(); + return -1; + } + + if (!eglInitialize(ec->egl_display, &major, &minor)) { + weston_log("failed to initialize display\n"); + print_egl_error_state(); + return -1; + } + + return 0; +} + +WL_EXPORT int +gles2_renderer_output_state_create_and_bind(struct weston_output *output, EGLNativeWindowType window) +{ + struct gles2_output_state *state = gles2_renderer_output_state_create(output->compositor, window); + + if (!state) + return -1; + + gles2_renderer_output_bind(output, state); + + return 0; +} + +WL_EXPORT struct gles2_output_state * +gles2_renderer_output_state_create(struct weston_compositor *ec, EGLNativeWindowType window) +{ + struct gles2_output_state *state = calloc(1, sizeof *state); + + if (!state) + return NULL; + + state->egl_surface = + eglCreateWindowSurface(ec->egl_display, + ec->egl_config, + window, NULL); + + if (state->egl_surface == EGL_NO_SURFACE) { + weston_log("failed to create egl surface\n"); + free(state); + return NULL; + } + + return state; +} + +WL_EXPORT void +gles2_renderer_output_state_destroy(struct weston_compositor *ec, struct gles2_output_state *state) +{ + eglDestroySurface(ec->egl_display, state->egl_surface); + + free(state); +} + +WL_EXPORT void +gles2_renderer_output_bind(struct weston_output *output, struct gles2_output_state *state) +{ + output->renderer_state = state; +} + +WL_EXPORT void +gles2_renderer_output_unbind(struct weston_output *output) +{ + gles2_renderer_output_state_destroy(output->compositor, get_output_state(output)); +} WL_EXPORT void gles2_renderer_destroy(struct weston_compositor *ec) { if (ec->has_bind_display) ec->unbind_display(ec->egl_display, ec->wl_display); + + /* Work around crash in egl_dri2.c's dri2_make_current() - when does this apply? */ + eglMakeCurrent(ec->egl_display, + EGL_NO_SURFACE, EGL_NO_SURFACE, + EGL_NO_CONTEXT); + + eglTerminate(ec->egl_display); + eglReleaseThread(); +} + +WL_EXPORT int +gles2_renderer_init(struct weston_compositor *ec, EGLNativeDisplayType display, int alpha) +{ + EGLint n; + + const EGLint config_attribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_ALPHA_SIZE, alpha ? 1 : 0, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_NONE + }; + + if (init_display(ec, display) < 0) + return -1; + + if (!eglChooseConfig(ec->egl_display, config_attribs, + &ec->egl_config, 1, &n) || n != 1) { + weston_log("failed to choose config: %d\n", n); + print_egl_error_state(); + return -1; + } + + return 0; +} + +WL_EXPORT EGLDisplay +gles2_renderer_init_without_config(struct weston_compositor *ec, EGLNativeDisplayType display) +{ + if (init_display(ec, display) < 0) + return EGL_NO_DISPLAY; + else + return ec->egl_display; +} + +void +gles2_renderer_select_config(struct weston_compositor *ec, EGLConfig config) +{ + ec->egl_config = config; } WL_EXPORT int -gles2_renderer_init(struct weston_compositor *ec) +gles2_renderer_outputs_ready(struct weston_compositor *ec) { - struct gles2_renderer *renderer; const char *extensions; int has_egl_image_external = 0; - struct weston_output *output; + struct gles2_output_state *output; EGLBoolean ret; static const EGLint context_attribs[] = { @@ -1182,10 +1346,6 @@ gles2_renderer_init(struct weston_compositor *ec) EGL_NONE }; - renderer = malloc(sizeof *renderer); - if (renderer == NULL) - return -1; - if (!eglBindAPI(EGL_OPENGL_ES_API)) { weston_log("failed to bind EGL_OPENGL_ES_API\n"); print_egl_error_state(); @@ -1202,8 +1362,8 @@ gles2_renderer_init(struct weston_compositor *ec) return -1; } - output = container_of(ec->output_list.next, - struct weston_output, link); + output = get_output_state(container_of(ec->output_list.next, + struct weston_output, link)); ret = eglMakeCurrent(ec->egl_display, output->egl_surface, output->egl_surface, ec->egl_context); if (ret == EGL_FALSE) { @@ -1289,12 +1449,6 @@ gles2_renderer_init(struct weston_compositor *ec) vertex_shader, solid_fragment_shader) < 0) return -1; - renderer->base.repaint_output = gles2_renderer_repaint_output; - renderer->base.flush_damage = gles2_renderer_flush_damage; - renderer->base.attach = gles2_renderer_attach; - renderer->base.destroy_surface = gles2_renderer_destroy_surface; - ec->renderer = &renderer->base; - weston_log("GL ES 2 renderer features:\n"); weston_log_continue(STAMP_SPACE "read-back format: %s\n", ec->read_format == GL_BGRA_EXT ? "BGRA" : "RGBA"); @@ -1303,5 +1457,6 @@ gles2_renderer_init(struct weston_compositor *ec) weston_log_continue(STAMP_SPACE "EGL Wayland extension: %s\n", ec->has_bind_display ? "yes" : "no"); + return 0; } -- 1.7.12.4 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel