Move EGLConfig, EGLContext and EGLDisplay fields into gles2-renderer.

This moves the EGLConfig, EGLContext and EGLDisplay fields into
gles2-renderer. It also moves EGLDisplay creation and EGLConfig
selection into gles2-renderer.
John Kåre Alsaker 12 years ago committed by Kristian Høgsberg
parent 94659274b4
commit 1b7ad160a3
  1. 150
      src/compositor-android.c
  2. 39
      src/compositor-drm.c
  3. 80
      src/compositor-rpi.c
  4. 48
      src/compositor-wayland.c
  5. 58
      src/compositor-x11.c
  6. 11
      src/compositor.h
  7. 200
      src/gles2-renderer.c

@ -78,42 +78,6 @@ to_android_compositor(struct weston_compositor *base)
return container_of(base, struct android_compositor, base); return container_of(base, struct android_compositor, base);
} }
static const char *
egl_error_string(EGLint code)
{
#define MYERRCODE(x) case x: return #x;
switch (code) {
MYERRCODE(EGL_SUCCESS)
MYERRCODE(EGL_NOT_INITIALIZED)
MYERRCODE(EGL_BAD_ACCESS)
MYERRCODE(EGL_BAD_ALLOC)
MYERRCODE(EGL_BAD_ATTRIBUTE)
MYERRCODE(EGL_BAD_CONTEXT)
MYERRCODE(EGL_BAD_CONFIG)
MYERRCODE(EGL_BAD_CURRENT_SURFACE)
MYERRCODE(EGL_BAD_DISPLAY)
MYERRCODE(EGL_BAD_SURFACE)
MYERRCODE(EGL_BAD_MATCH)
MYERRCODE(EGL_BAD_PARAMETER)
MYERRCODE(EGL_BAD_NATIVE_PIXMAP)
MYERRCODE(EGL_BAD_NATIVE_WINDOW)
MYERRCODE(EGL_CONTEXT_LOST)
default:
return "unknown";
}
#undef MYERRCODE
}
static void
print_egl_error_state(void)
{
EGLint code;
code = eglGetError();
weston_log("EGL error state: %s (0x%04lx)\n",
egl_error_string(code), (long)code);
}
static void static void
android_finish_frame(void *data) android_finish_frame(void *data)
{ {
@ -318,116 +282,26 @@ android_seat_create(struct android_compositor *compositor)
return seat; return seat;
} }
static int
android_egl_choose_config(struct android_compositor *compositor,
struct android_framebuffer *fb,
const EGLint *attribs)
{
EGLBoolean ret;
EGLint count = 0;
EGLint matched = 0;
EGLConfig *configs;
int i;
/*
* The logic is copied from Android frameworks/base/services/
* surfaceflinger/DisplayHardware/DisplayHardware.cpp
*/
compositor->base.egl_config = NULL;
ret = eglGetConfigs(compositor->base.egl_display, NULL, 0, &count);
if (ret == EGL_FALSE || count < 1)
return -1;
configs = calloc(count, sizeof *configs);
if (!configs)
return -1;
ret = eglChooseConfig(compositor->base.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,
configs[i], EGL_NATIVE_VISUAL_ID,
&id);
if (ret == EGL_FALSE)
continue;
if (id > 0 && fb->format == id) {
compositor->base.egl_config = configs[i];
break;
}
}
out:
free(configs);
if (!compositor->base.egl_config)
return -1;
return 0;
}
static int static int
android_init_egl(struct android_compositor *compositor, android_init_egl(struct android_compositor *compositor,
struct android_output *output) struct android_output *output)
{ {
EGLint eglmajor, eglminor; EGLint visual_id = output->fb->format;
int ret;
static const EGLint config_attrs[] = { if (gles2_renderer_create(&compositor->base,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_DEFAULT_DISPLAY, gles2_renderer_opaque_attribs,
EGL_RED_SIZE, 1, &visual_id) < 0)
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_ALPHA_SIZE, 0,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
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; return -1;
}
ret = eglInitialize(compositor->base.egl_display, &eglmajor, &eglminor);
if (!ret) {
weston_log("Failed to initialise EGL.\n");
print_egl_error_state();
return -1;
}
ret = android_egl_choose_config(compositor, output->fb, config_attrs);
if (ret < 0) {
weston_log("Failed to find an EGL config.\n");
print_egl_error_state();
return -1;
}
if (gles2_renderer_output_create(&output->base, if (gles2_renderer_output_create(&output->base,
output->fb->native_window) < 0) output->fb->native_window) < 0) {
gles2_renderer_destroy(&compositor->base);
return -1; return -1;
}
return 0; 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 static void
android_compositor_destroy(struct weston_compositor *base) android_compositor_destroy(struct weston_compositor *base)
{ {
@ -435,11 +309,11 @@ android_compositor_destroy(struct weston_compositor *base)
android_seat_destroy(compositor->seat); android_seat_destroy(compositor->seat);
gles2_renderer_destroy(base);
/* destroys outputs, too */ /* destroys outputs, too */
weston_compositor_shutdown(&compositor->base); weston_compositor_shutdown(&compositor->base);
android_fini_egl(compositor);
free(compositor); free(compositor);
} }
@ -475,12 +349,12 @@ android_compositor_create(struct wl_display *display, int argc, char *argv[],
compositor->seat = android_seat_create(compositor); compositor->seat = android_seat_create(compositor);
if (!compositor->seat) if (!compositor->seat)
goto err_egl; goto err_gles2;
return &compositor->base; return &compositor->base;
err_egl: err_gles2:
android_fini_egl(compositor); gles2_renderer_destroy(&compositor->base);
err_output: err_output:
android_output_destroy(&output->base); android_output_destroy(&output->base);
err_compositor: err_compositor:

@ -1003,18 +1003,8 @@ on_drm_input(int fd, uint32_t mask, void *data)
static int static int
init_egl(struct drm_compositor *ec, struct udev_device *device) init_egl(struct drm_compositor *ec, struct udev_device *device)
{ {
EGLint major, minor, n;
const char *filename, *sysnum; const char *filename, *sysnum;
int fd; 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); sysnum = udev_device_get_sysnum(device);
if (sysnum) if (sysnum)
@ -1037,20 +1027,10 @@ init_egl(struct drm_compositor *ec, struct udev_device *device)
ec->drm.fd = fd; ec->drm.fd = fd;
ec->gbm = gbm_create_device(ec->drm.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)) { if (gles2_renderer_create(&ec->base, ec->gbm, gles2_renderer_opaque_attribs,
weston_log("failed to initialize display\n"); NULL) < 0) {
return -1; gbm_device_destroy(ec->gbm);
}
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);
return -1; return -1;
} }
@ -1969,12 +1949,6 @@ drm_destroy(struct weston_compositor *ec)
gles2_renderer_destroy(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();
destroy_sprites(d); destroy_sprites(d);
gbm_device_destroy(d->gbm); gbm_device_destroy(d->gbm);
if (weston_launcher_drm_set_master(&d->base, d->drm.fd, 0) < 0) if (weston_launcher_drm_set_master(&d->base, d->drm.fd, 0) < 0)
@ -2257,12 +2231,9 @@ err_drm_source:
wl_event_source_remove(ec->drm_source); wl_event_source_remove(ec->drm_source);
wl_list_for_each_safe(weston_seat, next, &ec->base.seat_list, link) wl_list_for_each_safe(weston_seat, next, &ec->base.seat_list, link)
evdev_input_destroy(weston_seat); evdev_input_destroy(weston_seat);
eglMakeCurrent(ec->base.egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
EGL_NO_CONTEXT);
eglTerminate(ec->base.egl_display);
eglReleaseThread();
gbm_device_destroy(ec->gbm);
err_sprite: err_sprite:
gles2_renderer_destroy(&ec->base);
gbm_device_destroy(ec->gbm);
destroy_sprites(ec); destroy_sprites(ec);
err_udev_dev: err_udev_dev:
udev_device_unref(drm_device); udev_device_unref(drm_device);

@ -1089,7 +1089,7 @@ rpi_output_create(struct rpi_compositor *compositor)
(EGLNativeWindowType)&output->egl_window) < 0) (EGLNativeWindowType)&output->egl_window) < 0)
goto out_output; goto out_output;
if (!eglSurfaceAttrib(compositor->base.egl_display, if (!eglSurfaceAttrib(gles2_renderer_display(&compositor->base),
gles2_renderer_output_surface(&output->base), gles2_renderer_output_surface(&output->base),
EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED)) { EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED)) {
print_egl_error_state(); print_egl_error_state();
@ -1355,63 +1355,6 @@ evdev_input_destroy(struct weston_seat *seat_base)
free(seat); free(seat);
} }
static int
rpi_init_egl(struct rpi_compositor *compositor)
{
EGLint eglmajor, eglminor;
int ret;
EGLint num_config;
static const EGLint config_attrs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT |
EGL_SWAP_BEHAVIOR_PRESERVED_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
};
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;
}
ret = eglInitialize(compositor->base.egl_display, &eglmajor, &eglminor);
if (!ret) {
weston_log("Failed to initialise EGL.\n");
print_egl_error_state();
return -1;
}
ret = eglChooseConfig(compositor->base.egl_display, config_attrs,
&compositor->base.egl_config, 1, &num_config);
if (ret < 0 || num_config != 1) {
weston_log("Failed to find an EGL config (found %d configs).\n",
num_config);
print_egl_error_state();
return -1;
}
return 0;
}
static void
rpi_fini_egl(struct rpi_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 static void
rpi_compositor_destroy(struct weston_compositor *base) rpi_compositor_destroy(struct weston_compositor *base)
{ {
@ -1424,7 +1367,7 @@ rpi_compositor_destroy(struct weston_compositor *base)
/* destroys outputs, too */ /* destroys outputs, too */
weston_compositor_shutdown(&compositor->base); weston_compositor_shutdown(&compositor->base);
rpi_fini_egl(compositor); gles2_renderer_destroy(&compositor->base);
tty_destroy(compositor->tty); tty_destroy(compositor->tty);
bcm_host_deinit(); bcm_host_deinit();
@ -1506,6 +1449,16 @@ rpi_compositor_create(struct wl_display *display, int argc, char *argv[],
struct rpi_compositor *compositor; struct rpi_compositor *compositor;
const char *seat = default_seat; const char *seat = default_seat;
uint32_t key; uint32_t key;
static const EGLint config_attrs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT |
EGL_SWAP_BEHAVIOR_PRESERVED_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
};
weston_log("initializing Raspberry Pi backend\n"); weston_log("initializing Raspberry Pi backend\n");
@ -1556,18 +1509,19 @@ rpi_compositor_create(struct wl_display *display, int argc, char *argv[],
*/ */
bcm_host_init(); bcm_host_init();
if (rpi_init_egl(compositor) < 0) if (gles2_renderer_create(&compositor->base, EGL_DEFAULT_DISPLAY,
config_attrs, NULL) < 0)
goto out_tty; goto out_tty;
if (rpi_output_create(compositor) < 0) if (rpi_output_create(compositor) < 0)
goto out_egl; goto out_gles2;
evdev_input_create(&compositor->base, compositor->udev, seat); evdev_input_create(&compositor->base, compositor->udev, seat);
return &compositor->base; return &compositor->base;
out_egl: out_gles2:
rpi_fini_egl(compositor); gles2_renderer_destroy(&compositor->base);
out_tty: out_tty:
tty_destroy(compositor->tty); tty_destroy(compositor->tty);

@ -241,41 +241,6 @@ create_border(struct wayland_compositor *c)
pixman_image_unref(image); 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 static void
frame_done(void *data, struct wl_callback *callback, uint32_t time) frame_done(void *data, struct wl_callback *callback, uint32_t time)
{ {
@ -827,7 +792,9 @@ wayland_compositor_create(struct wl_display *display,
wl_display_dispatch(c->parent.wl_display); wl_display_dispatch(c->parent.wl_display);
c->base.wl_display = display; c->base.wl_display = display;
if (wayland_compositor_init_egl(c) < 0) if (gles2_renderer_create(&c->base, c->parent.wl_display,
gles2_renderer_alpha_attribs,
NULL) < 0)
goto err_display; goto err_display;
c->base.destroy = wayland_destroy; c->base.destroy = wayland_destroy;
@ -840,9 +807,10 @@ wayland_compositor_create(struct wl_display *display,
/* requires border fields */ /* requires border fields */
if (wayland_compositor_create_output(c, width, height) < 0) if (wayland_compositor_create_output(c, width, height) < 0)
goto err_display; goto err_gles2;
/* requires gles2_renderer_init */ /* requires gles2_renderer_output_state_create called
* by wayland_compositor_create_output */
create_border(c); create_border(c);
loop = wl_display_get_event_loop(c->base.wl_display); loop = wl_display_get_event_loop(c->base.wl_display);
@ -852,12 +820,14 @@ wayland_compositor_create(struct wl_display *display,
wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE, wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
wayland_compositor_handle_event, c); wayland_compositor_handle_event, c);
if (c->parent.wl_source == NULL) if (c->parent.wl_source == NULL)
goto err_display; goto err_gles2;
wl_event_source_check(c->parent.wl_source); wl_event_source_check(c->parent.wl_source);
return &c->base; return &c->base;
err_gles2:
gles2_renderer_destroy(&c->base);
err_display: err_display:
wl_display_disconnect(c->parent.wl_display); wl_display_disconnect(c->parent.wl_display);
err_compositor: err_compositor:

@ -307,53 +307,6 @@ x11_input_destroy(struct x11_compositor *compositor)
weston_seat_release(&compositor->core_seat); 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 static void
x11_output_repaint(struct weston_output *output_base, x11_output_repaint(struct weston_output *output_base,
pixman_region32_t *damage) pixman_region32_t *damage)
@ -1153,7 +1106,7 @@ x11_destroy(struct weston_compositor *ec)
weston_compositor_shutdown(ec); /* destroys outputs, too */ weston_compositor_shutdown(ec); /* destroys outputs, too */
x11_compositor_fini_egl(compositor); gles2_renderer_destroy(ec);
XCloseDisplay(compositor->dpy); XCloseDisplay(compositor->dpy);
free(ec); free(ec);
@ -1201,14 +1154,15 @@ x11_compositor_create(struct wl_display *display,
x11_compositor_get_resources(c); x11_compositor_get_resources(c);
c->base.wl_display = display; c->base.wl_display = display;
if (x11_compositor_init_egl(c) < 0) if (gles2_renderer_create(&c->base, c->dpy, gles2_renderer_opaque_attribs,
NULL) < 0)
goto err_xdisplay; goto err_xdisplay;
c->base.destroy = x11_destroy; c->base.destroy = x11_destroy;
c->base.restore = x11_restore; c->base.restore = x11_restore;
if (x11_input_create(c, no_input) < 0) if (x11_input_create(c, no_input) < 0)
goto err_egl; goto err_gles2;
width = option_width ? option_width : 1024; width = option_width ? option_width : 1024;
height = option_height ? option_height : 640; height = option_height ? option_height : 640;
@ -1252,8 +1206,8 @@ x11_compositor_create(struct wl_display *display,
err_x11_input: err_x11_input:
x11_input_destroy(c); x11_input_destroy(c);
err_egl: err_gles2:
x11_compositor_fini_egl(c); gles2_renderer_destroy(&c->base);
err_xdisplay: err_xdisplay:
XCloseDisplay(c->dpy); XCloseDisplay(c->dpy);
err_free: err_free:

@ -286,9 +286,6 @@ struct weston_renderer {
struct weston_compositor { struct weston_compositor {
struct wl_signal destroy_signal; struct wl_signal destroy_signal;
EGLDisplay egl_display;
EGLContext egl_context;
EGLConfig egl_config;
struct weston_shader texture_shader_rgba; struct weston_shader texture_shader_rgba;
struct weston_shader texture_shader_rgbx; struct weston_shader texture_shader_rgbx;
struct weston_shader texture_shader_egl_external; struct weston_shader texture_shader_egl_external;
@ -838,6 +835,14 @@ weston_surface_destroy(struct weston_surface *surface);
int int
weston_output_switch_mode(struct weston_output *output, struct weston_mode *mode); weston_output_switch_mode(struct weston_output *output, struct weston_mode *mode);
extern const EGLint gles2_renderer_opaque_attribs[];
extern const EGLint gles2_renderer_alpha_attribs[];
int
gles2_renderer_create(struct weston_compositor *ec, EGLNativeDisplayType display,
const EGLint *attribs, const EGLint *visual_id);
EGLDisplay
gles2_renderer_display(struct weston_compositor *ec);
int int
gles2_renderer_output_create(struct weston_output *output, gles2_renderer_output_create(struct weston_output *output,
EGLNativeWindowType window); EGLNativeWindowType window);

@ -31,22 +31,31 @@
#include "compositor.h" #include "compositor.h"
struct gles2_output_state {
EGLSurface egl_surface;
};
struct gles2_renderer { struct gles2_renderer {
struct weston_renderer base; struct weston_renderer base;
int fragment_shader_debug; int fragment_shader_debug;
};
struct gles2_output_state { EGLDisplay egl_display;
EGLSurface egl_surface; EGLContext egl_context;
EGLConfig egl_config;
}; };
static inline struct gles2_output_state * static inline struct gles2_output_state *
get_output_state(struct weston_output *output) get_output_state(struct weston_output *output)
{ {
return (struct gles2_output_state *)output->renderer_state; 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 * static const char *
egl_error_string(EGLint code) egl_error_string(EGLint code)
{ {
@ -719,6 +728,7 @@ gles2_renderer_repaint_output(struct weston_output *output,
{ {
struct gles2_output_state *go = get_output_state(output); struct gles2_output_state *go = get_output_state(output);
struct weston_compositor *compositor = output->compositor; struct weston_compositor *compositor = output->compositor;
struct gles2_renderer *gr = get_renderer(compositor);
EGLBoolean ret; EGLBoolean ret;
static int errored; static int errored;
int32_t width, height, i; int32_t width, height, i;
@ -730,8 +740,8 @@ gles2_renderer_repaint_output(struct weston_output *output,
glViewport(0, 0, width, height); glViewport(0, 0, width, height);
ret = eglMakeCurrent(compositor->egl_display, go->egl_surface, ret = eglMakeCurrent(gr->egl_display, go->egl_surface,
go->egl_surface, compositor->egl_context); go->egl_surface, gr->egl_context);
if (ret == EGL_FALSE) { if (ret == EGL_FALSE) {
if (errored) if (errored)
return; return;
@ -767,7 +777,7 @@ gles2_renderer_repaint_output(struct weston_output *output,
wl_signal_emit(&output->frame_signal, output); wl_signal_emit(&output->frame_signal, output);
ret = eglSwapBuffers(compositor->egl_display, go->egl_surface); ret = eglSwapBuffers(gr->egl_display, go->egl_surface);
if (ret == EGL_FALSE && !errored) { if (ret == EGL_FALSE && !errored) {
errored = 1; errored = 1;
weston_log("Failed in eglSwapBuffers.\n"); weston_log("Failed in eglSwapBuffers.\n");
@ -855,12 +865,13 @@ static void
gles2_renderer_attach(struct weston_surface *es, struct wl_buffer *buffer) gles2_renderer_attach(struct weston_surface *es, struct wl_buffer *buffer)
{ {
struct weston_compositor *ec = es->compositor; struct weston_compositor *ec = es->compositor;
struct gles2_renderer *gr = get_renderer(ec);
EGLint attribs[3], format; EGLint attribs[3], format;
int i, num_planes; int i, num_planes;
if (!buffer) { if (!buffer) {
for (i = 0; i < es->num_images; i++) { for (i = 0; i < es->num_images; i++) {
ec->destroy_image(ec->egl_display, es->images[i]); ec->destroy_image(gr->egl_display, es->images[i]);
es->images[i] = NULL; es->images[i] = NULL;
} }
es->num_images = 0; es->num_images = 0;
@ -882,10 +893,10 @@ gles2_renderer_attach(struct weston_surface *es, struct wl_buffer *buffer)
es->shader = &ec->texture_shader_rgbx; es->shader = &ec->texture_shader_rgbx;
else else
es->shader = &ec->texture_shader_rgba; es->shader = &ec->texture_shader_rgba;
} else if (ec->query_buffer(ec->egl_display, buffer, } else if (ec->query_buffer(gr->egl_display, buffer,
EGL_TEXTURE_FORMAT, &format)) { EGL_TEXTURE_FORMAT, &format)) {
for (i = 0; i < es->num_images; i++) for (i = 0; i < es->num_images; i++)
ec->destroy_image(ec->egl_display, es->images[i]); ec->destroy_image(gr->egl_display, es->images[i]);
es->num_images = 0; es->num_images = 0;
es->target = GL_TEXTURE_2D; es->target = GL_TEXTURE_2D;
switch (format) { switch (format) {
@ -919,7 +930,7 @@ gles2_renderer_attach(struct weston_surface *es, struct wl_buffer *buffer)
attribs[0] = EGL_WAYLAND_PLANE_WL; attribs[0] = EGL_WAYLAND_PLANE_WL;
attribs[1] = i; attribs[1] = i;
attribs[2] = EGL_NONE; attribs[2] = EGL_NONE;
es->images[i] = ec->create_image(ec->egl_display, es->images[i] = ec->create_image(gr->egl_display,
NULL, NULL,
EGL_WAYLAND_BUFFER_WL, EGL_WAYLAND_BUFFER_WL,
buffer, attribs); buffer, attribs);
@ -945,12 +956,13 @@ static void
gles2_renderer_destroy_surface(struct weston_surface *surface) gles2_renderer_destroy_surface(struct weston_surface *surface)
{ {
struct weston_compositor *ec = surface->compositor; struct weston_compositor *ec = surface->compositor;
struct gles2_renderer *gr = get_renderer(ec);
int i; int i;
glDeleteTextures(surface->num_textures, surface->textures); glDeleteTextures(surface->num_textures, surface->textures);
for (i = 0; i < surface->num_images; i++) for (i = 0; i < surface->num_images; i++)
ec->destroy_image(ec->egl_display, surface->images[i]); ec->destroy_image(gr->egl_display, surface->images[i]);
} }
static const char vertex_shader[] = static const char vertex_shader[] =
@ -1233,14 +1245,15 @@ gles2_renderer_output_create(struct weston_output *output,
EGLNativeWindowType window) EGLNativeWindowType window)
{ {
struct weston_compositor *ec = output->compositor; struct weston_compositor *ec = output->compositor;
struct gles2_renderer *gr = get_renderer(ec);
struct gles2_output_state *go = calloc(1, sizeof *go); struct gles2_output_state *go = calloc(1, sizeof *go);
if (!go) if (!go)
return -1; return -1;
go->egl_surface = go->egl_surface =
eglCreateWindowSurface(ec->egl_display, eglCreateWindowSurface(gr->egl_display,
ec->egl_config, gr->egl_config,
window, NULL); window, NULL);
if (go->egl_surface == EGL_NO_SURFACE) { if (go->egl_surface == EGL_NO_SURFACE) {
@ -1249,7 +1262,7 @@ gles2_renderer_output_create(struct weston_output *output,
return -1; return -1;
} }
if (ec->egl_context == NULL) if (gr->egl_context == NULL)
if (gles2_renderer_setup(ec, go->egl_surface) < 0) { if (gles2_renderer_setup(ec, go->egl_surface) < 0) {
free(go); free(go);
return -1; return -1;
@ -1263,9 +1276,10 @@ gles2_renderer_output_create(struct weston_output *output,
WL_EXPORT void WL_EXPORT void
gles2_renderer_output_destroy(struct weston_output *output) gles2_renderer_output_destroy(struct weston_output *output)
{ {
struct gles2_renderer *gr = get_renderer(output->compositor);
struct gles2_output_state *go = get_output_state(output); struct gles2_output_state *go = get_output_state(output);
eglDestroySurface(output->compositor->egl_display, go->egl_surface); eglDestroySurface(gr->egl_display, go->egl_surface);
free(go); free(go);
} }
@ -1279,8 +1293,131 @@ gles2_renderer_output_surface(struct weston_output *output)
WL_EXPORT void WL_EXPORT void
gles2_renderer_destroy(struct weston_compositor *ec) gles2_renderer_destroy(struct weston_compositor *ec)
{ {
struct gles2_renderer *gr = get_renderer(ec);
if (ec->has_bind_display) if (ec->has_bind_display)
ec->unbind_display(ec->egl_display, ec->wl_display); ec->unbind_display(gr->egl_display, ec->wl_display);
/* Work around crash in egl_dri2.c's dri2_make_current() - when does this apply? */
eglMakeCurrent(gr->egl_display,
EGL_NO_SURFACE, EGL_NO_SURFACE,
EGL_NO_CONTEXT);
eglTerminate(gr->egl_display);
eglReleaseThread();
}
static int
egl_choose_config(struct gles2_renderer *gr, const EGLint *attribs,
const EGLint *visual_id)
{
EGLint count = 0;
EGLint matched = 0;
EGLConfig *configs;
int i;
if (!eglGetConfigs(gr->egl_display, NULL, 0, &count) || count < 1)
return -1;
configs = calloc(count, sizeof *configs);
if (!configs)
return -1;
if (!eglChooseConfig(gr->egl_display, attribs, configs,
count, &matched))
goto out;
for (i = 0; i < matched; ++i) {
EGLint id;
if (visual_id) {
if (!eglGetConfigAttrib(gr->egl_display,
configs[i], EGL_NATIVE_VISUAL_ID,
&id))
continue;
if (id != *visual_id)
continue;
}
gr->egl_config = configs[i];
free(configs);
return 0;
}
out:
free(configs);
return -1;
}
WL_EXPORT const EGLint gles2_renderer_opaque_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
};
WL_EXPORT const EGLint gles2_renderer_alpha_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
};
WL_EXPORT int
gles2_renderer_create(struct weston_compositor *ec, EGLNativeDisplayType display,
const EGLint *attribs, const EGLint *visual_id)
{
struct gles2_renderer *gr;
EGLint major, minor;
gr = calloc(1, sizeof *gr);
if (gr == NULL)
return -1;
gr->base.repaint_output = gles2_renderer_repaint_output;
gr->base.flush_damage = gles2_renderer_flush_damage;
gr->base.attach = gles2_renderer_attach;
gr->base.destroy_surface = gles2_renderer_destroy_surface;
gr->egl_display = eglGetDisplay(display);
if (gr->egl_display == EGL_NO_DISPLAY) {
weston_log("failed to create display\n");
goto err_egl;
}
if (!eglInitialize(gr->egl_display, &major, &minor)) {
weston_log("failed to initialize display\n");
goto err_egl;
}
if (egl_choose_config(gr, attribs, visual_id) < 0) {
weston_log("failed to choose EGL config\n");
goto err_egl;
}
ec->renderer = &gr->base;
return 0;
err_egl:
print_egl_error_state();
free(gr);
return -1;
}
WL_EXPORT EGLDisplay
gles2_renderer_display(struct weston_compositor *ec)
{
return get_renderer(ec)->egl_display;
} }
static int static int
@ -1340,7 +1477,7 @@ fragment_debug_binding(struct wl_seat *seat, uint32_t time, uint32_t key,
static int static int
gles2_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface) gles2_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)
{ {
struct gles2_renderer *renderer; struct gles2_renderer *gr = get_renderer(ec);
const char *extensions; const char *extensions;
EGLBoolean ret; EGLBoolean ret;
@ -1349,35 +1486,31 @@ gles2_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)
EGL_NONE EGL_NONE
}; };
renderer = calloc(1, sizeof *renderer);
if (renderer == NULL)
return -1;
if (!eglBindAPI(EGL_OPENGL_ES_API)) { if (!eglBindAPI(EGL_OPENGL_ES_API)) {
weston_log("failed to bind EGL_OPENGL_ES_API\n"); weston_log("failed to bind EGL_OPENGL_ES_API\n");
print_egl_error_state(); print_egl_error_state();
return -1; return -1;
} }
log_egl_config_info(ec->egl_display, ec->egl_config); log_egl_config_info(gr->egl_display, gr->egl_config);
ec->egl_context = eglCreateContext(ec->egl_display, ec->egl_config, gr->egl_context = eglCreateContext(gr->egl_display, gr->egl_config,
EGL_NO_CONTEXT, context_attribs); EGL_NO_CONTEXT, context_attribs);
if (ec->egl_context == NULL) { if (gr->egl_context == NULL) {
weston_log("failed to create context\n"); weston_log("failed to create context\n");
print_egl_error_state(); print_egl_error_state();
return -1; return -1;
} }
ret = eglMakeCurrent(ec->egl_display, egl_surface, ret = eglMakeCurrent(gr->egl_display, egl_surface,
egl_surface, ec->egl_context); egl_surface, gr->egl_context);
if (ret == EGL_FALSE) { if (ret == EGL_FALSE) {
weston_log("Failed to make EGL context current.\n"); weston_log("Failed to make EGL context current.\n");
print_egl_error_state(); print_egl_error_state();
return -1; return -1;
} }
log_egl_gl_info(ec->egl_display); log_egl_gl_info(gr->egl_display);
ec->image_target_texture_2d = ec->image_target_texture_2d =
(void *) eglGetProcAddress("glEGLImageTargetTexture2DOES"); (void *) eglGetProcAddress("glEGLImageTargetTexture2DOES");
@ -1415,7 +1548,7 @@ gles2_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)
ec->has_egl_image_external = 1; ec->has_egl_image_external = 1;
extensions = extensions =
(const char *) eglQueryString(ec->egl_display, EGL_EXTENSIONS); (const char *) eglQueryString(gr->egl_display, EGL_EXTENSIONS);
if (!extensions) { if (!extensions) {
weston_log("Retrieving EGL extension string failed.\n"); weston_log("Retrieving EGL extension string failed.\n");
return -1; return -1;
@ -1424,19 +1557,13 @@ gles2_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)
if (strstr(extensions, "EGL_WL_bind_wayland_display")) if (strstr(extensions, "EGL_WL_bind_wayland_display"))
ec->has_bind_display = 1; ec->has_bind_display = 1;
if (ec->has_bind_display) { if (ec->has_bind_display) {
ret = ec->bind_display(ec->egl_display, ec->wl_display); ret = ec->bind_display(gr->egl_display, ec->wl_display);
if (!ret) if (!ret)
ec->has_bind_display = 0; ec->has_bind_display = 0;
} }
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
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;
if (compile_shaders(ec)) if (compile_shaders(ec))
return -1; return -1;
@ -1451,5 +1578,6 @@ gles2_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)
weston_log_continue(STAMP_SPACE "EGL Wayland extension: %s\n", weston_log_continue(STAMP_SPACE "EGL Wayland extension: %s\n",
ec->has_bind_display ? "yes" : "no"); ec->has_bind_display ? "yes" : "no");
return 0; return 0;
} }

Loading…
Cancel
Save