[PATCH v4 01/10] Move weston_output EGL state into gles2-renderer.
John Kåre Alsaker
john.kare.alsaker at gmail.com
Mon Oct 29 14:17:09 PDT 2012
---
src/compositor-android.c | 21 ++++++-------
src/compositor-drm.c | 61 ++++++++++++++++++--------------------
src/compositor-wayland.c | 21 ++++++-------
src/compositor-x11.c | 18 +++++------
src/compositor.h | 16 ++++++++--
src/gles2-renderer.c | 77 +++++++++++++++++++++++++++++++++++++++++-------
6 files changed, 133 insertions(+), 81 deletions(-)
diff --git a/src/compositor-android.c b/src/compositor-android.c
index 3c0273a..281f093 100644
--- a/src/compositor-android.c
+++ b/src/compositor-android.c
@@ -145,6 +145,9 @@ android_output_destroy(struct weston_output *base)
wl_list_remove(&output->base.link);
weston_output_destroy(&output->base);
+ gles2_renderer_output_state_destroy(base->compositor,
+ base->renderer_state);
+
android_framebuffer_destroy(output->fb);
free(output);
@@ -374,6 +377,7 @@ android_init_egl(struct android_compositor *compositor,
{
EGLint eglmajor, eglminor;
int ret;
+ struct gles2_output_state *go;
static const EGLint config_attrs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
@@ -406,16 +410,12 @@ android_init_egl(struct android_compositor *compositor,
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();
+ go = gles2_renderer_output_state_create(&compositor->base,
+ output->fb->native_window);
+ if (!go)
return -1;
- }
+
+ gles2_renderer_output_bind(&output->base, go);
return 0;
}
@@ -478,9 +478,6 @@ 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;
-
compositor->seat = android_seat_create(compositor);
if (!compositor->seat)
goto err_egl;
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 1730cb2..8834f4b 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -861,7 +861,9 @@ 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_state_destroy(output_base->compositor,
+ output_base->renderer_state);
+
gbm_surface_destroy(output->surface);
weston_plane_release(&output->fb_plane);
@@ -907,7 +909,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 *go;
if (output_base == NULL) {
weston_log("output is NULL.\n");
@@ -967,15 +969,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);
+ go = 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 (!go)
+ goto err_gbm;
ret = drmModeSetCrtc(ec->drm.fd,
output->crtc_id,
@@ -983,7 +980,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 +1002,12 @@ 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_state_destroy(output_base->compositor,
+ output_base->renderer_state);
+
gbm_surface_destroy(output->surface);
- output->base.egl_surface = egl_surface;
output->surface = surface;
+ gles2_renderer_output_bind(&output->base, go);
/*update output*/
output->base.current = &drm_mode->base;
@@ -1016,8 +1015,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, go);
+err_gbm:
gbm_surface_destroy(surface);
return -1;
}
@@ -1317,6 +1317,7 @@ create_output_for_connector(struct drm_compositor *ec,
int i;
char name[32];
const char *type_name;
+ struct gles2_output_state *state;
i = find_crtc_for_connector(ec, resources, connector);
if (i < 0) {
@@ -1445,15 +1446,16 @@ 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);
+
+ state = gles2_renderer_output_state_create(&ec->base, output->surface);
+ if (!state)
+ goto err_output;
+
+ /* this requires output->base.compositor to be initialized */
+ gles2_renderer_output_bind(&output->base, state);
output->cursor_bo[0] =
gbm_bo_create(ec->gbm, 64, 64, GBM_FORMAT_ARGB8888,
@@ -1473,10 +1475,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 +1501,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,
@@ -2274,9 +2273,6 @@ drm_compositor_create(struct wl_display *display,
goto err_sprite;
}
- if (gles2_renderer_init(&ec->base) < 0)
- goto err_egl;
-
path = NULL;
evdev_input_create(&ec->base, ec->udev, seat);
@@ -2314,7 +2310,6 @@ err_drm_source:
wl_event_source_remove(ec->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);
diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
index 56759fc..87c1257 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -317,9 +317,10 @@ 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_state_destroy(output_base->compositor,
+ output_base->renderer_state);
+
wl_egl_window_destroy(output->parent.egl_window);
free(output);
@@ -333,6 +334,7 @@ wayland_compositor_create_output(struct wayland_compositor *c,
int width, int height)
{
struct wayland_output *output;
+ struct gles2_output_state *go;
output = malloc(sizeof *output);
if (output == NULL)
@@ -373,13 +375,12 @@ 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");
+ go = gles2_renderer_output_state_create(&c->base,
+ output->parent.egl_window);
+ if (!go)
goto cleanup_window;
- }
+
+ gles2_renderer_output_bind(&output->base, go);
output->parent.shell_surface =
wl_shell_get_shell_surface(c->parent.shell,
@@ -846,10 +847,6 @@ wayland_compositor_create(struct wl_display *display,
if (wayland_compositor_create_output(c, width, height) < 0)
goto err_display;
- /* requires wayland_compositor_create_output */
- if (gles2_renderer_init(&c->base) < 0)
- goto err_display;
-
/* requires gles2_renderer_init */
create_border(c);
diff --git a/src/compositor-x11.c b/src/compositor-x11.c
index 22514c9..2368869 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -368,8 +368,8 @@ 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_state_destroy(output_base->compositor,
+ output_base->renderer_state);
xcb_destroy_window(compositor->conn, output->window);
@@ -485,6 +485,7 @@ x11_compositor_create_output(struct x11_compositor *c, int x, int y,
xcb_screen_iterator_t iter;
struct wm_normal_hints normal_hints;
struct wl_event_loop *loop;
+ struct gles2_output_state *go;
uint32_t mask = XCB_CW_EVENT_MASK | XCB_CW_CURSOR;
uint32_t values[2] = {
XCB_EVENT_MASK_EXPOSURE |
@@ -575,13 +576,11 @@ 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");
+ go = gles2_renderer_output_state_create(&c->base, output->window);
+ if (!go)
return NULL;
- }
+
+ gles2_renderer_output_bind(&output->base, go);
loop = wl_display_get_event_loop(c->base.wl_display);
output->finish_frame_timer =
@@ -1193,9 +1192,6 @@ 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;
-
c->xcb_source =
wl_event_loop_add_fd(c->base.input_loop,
xcb_get_file_descriptor(c->conn),
diff --git a/src/compositor.h b/src/compositor.h
index 3176bfd..51eabfd 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,17 @@ weston_surface_destroy(struct weston_surface *surface);
int
weston_output_switch_mode(struct weston_output *output, struct weston_mode *mode);
-int
-gles2_renderer_init(struct weston_compositor *ec);
+struct gles2_output_state;
+
+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 *go);
+void
+gles2_renderer_output_bind(struct weston_output *output,
+ struct gles2_output_state *go);
void
gles2_renderer_destroy(struct weston_compositor *ec);
diff --git a/src/gles2-renderer.c b/src/gles2-renderer.c
index 544cc15..f379760 100644
--- a/src/gles2-renderer.c
+++ b/src/gles2-renderer.c
@@ -30,6 +30,17 @@
#include "compositor.h"
+struct gles2_output_state {
+ EGLSurface egl_surface;
+};
+
+
+static inline struct gles2_output_state *
+get_output_state(struct weston_output *output)
+{
+ return (struct gles2_output_state *)output->renderer_state;
+}
+
static const char *
egl_error_string(EGLint code)
{
@@ -700,6 +711,7 @@ static void
gles2_renderer_repaint_output(struct weston_output *output,
pixman_region32_t *output_damage)
{
+ struct gles2_output_state *go = get_output_state(output);
struct weston_compositor *compositor = output->compositor;
EGLBoolean ret;
static int errored;
@@ -712,8 +724,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, go->egl_surface,
+ go->egl_surface, compositor->egl_context);
if (ret == EGL_FALSE) {
if (errored)
return;
@@ -749,7 +761,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, go->egl_surface);
if (ret == EGL_FALSE && !errored) {
errored = 1;
weston_log("Failed in eglSwapBuffers.\n");
@@ -1161,6 +1173,54 @@ struct gles2_renderer {
struct weston_renderer base;
};
+static int
+gles2_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface);
+
+WL_EXPORT struct gles2_output_state *
+gles2_renderer_output_state_create(struct weston_compositor *ec,
+ EGLNativeWindowType window)
+{
+ struct gles2_output_state *go = calloc(1, sizeof *go);
+
+ if (!go)
+ return NULL;
+
+ go->egl_surface =
+ eglCreateWindowSurface(ec->egl_display,
+ ec->egl_config,
+ window, NULL);
+
+ if (go->egl_surface == EGL_NO_SURFACE) {
+ weston_log("failed to create egl surface\n");
+ free(go);
+ return NULL;
+ }
+
+ if (ec->egl_context == NULL)
+ if (gles2_renderer_setup(ec, go->egl_surface) < 0) {
+ free(go);
+ return NULL;
+ }
+
+ return go;
+}
+
+WL_EXPORT void
+gles2_renderer_output_state_destroy(struct weston_compositor *ec,
+ struct gles2_output_state *go)
+{
+ eglDestroySurface(ec->egl_display, go->egl_surface);
+
+ free(go);
+}
+
+WL_EXPORT void
+gles2_renderer_output_bind(struct weston_output *output,
+ struct gles2_output_state *go)
+{
+ output->renderer_state = go;
+}
+
WL_EXPORT void
gles2_renderer_destroy(struct weston_compositor *ec)
{
@@ -1168,13 +1228,12 @@ gles2_renderer_destroy(struct weston_compositor *ec)
ec->unbind_display(ec->egl_display, ec->wl_display);
}
-WL_EXPORT int
-gles2_renderer_init(struct weston_compositor *ec)
+static int
+gles2_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)
{
struct gles2_renderer *renderer;
const char *extensions;
int has_egl_image_external = 0;
- struct weston_output *output;
EGLBoolean ret;
static const EGLint context_attribs[] = {
@@ -1202,10 +1261,8 @@ gles2_renderer_init(struct weston_compositor *ec)
return -1;
}
- output = container_of(ec->output_list.next,
- struct weston_output, link);
- ret = eglMakeCurrent(ec->egl_display, output->egl_surface,
- output->egl_surface, ec->egl_context);
+ ret = eglMakeCurrent(ec->egl_display, egl_surface,
+ egl_surface, ec->egl_context);
if (ret == EGL_FALSE) {
weston_log("Failed to make EGL context current.\n");
print_egl_error_state();
--
1.7.12.4
More information about the wayland-devel
mailing list