diff --git a/0001-gl-renderer-Take-a-list-of-acceptable-formats-in-cre.patch b/0001-gl-renderer-Take-a-list-of-acceptable-formats-in-cre.patch new file mode 100644 index 0000000..80c693c --- /dev/null +++ b/0001-gl-renderer-Take-a-list-of-acceptable-formats-in-cre.patch @@ -0,0 +1,277 @@ +From e76f185050e86116ad03fdc0119505dd8c3b367a Mon Sep 17 00:00:00 2001 +From: Derek Foreman +Date: Fri, 15 May 2015 12:12:39 -0500 +Subject: [PATCH 1/2] gl-renderer: Take a list of acceptable formats in create + functions + +Currently we pass either a single format or no formats to the gl renderer +create and output_create functions. We extend this to any number of +formats so we can allow fallback formats if we don't get our first pick. + +Reviewed-By: Bryce Harrington +Reviewed-By: Pekka Paalanen +Signed-off-by: Derek Foreman +--- + src/compositor-drm.c | 5 ++-- + src/compositor-fbdev.c | 4 +-- + src/compositor-wayland.c | 12 ++++---- + src/compositor-x11.c | 5 ++-- + src/gl-renderer.c | 71 ++++++++++++++++++++++++++++++++---------------- + src/gl-renderer.h | 6 ++-- + 6 files changed, 66 insertions(+), 37 deletions(-) + +diff --git a/src/compositor-drm.c b/src/compositor-drm.c +index 0cdb8f4..69bdcfd 100644 +--- a/src/compositor-drm.c ++++ b/src/compositor-drm.c +@@ -1398,7 +1398,7 @@ drm_compositor_create_gl_renderer(struct drm_compositor *ec) + + format = ec->format; + if (gl_renderer->create(&ec->base, EGL_PLATFORM_GBM_KHR, (void *) ec->gbm, +- gl_renderer->opaque_attribs, &format) < 0) { ++ gl_renderer->opaque_attribs, &format, 1) < 0) { + return -1; + } + +@@ -1620,7 +1620,8 @@ drm_output_init_egl(struct drm_output *output, struct drm_compositor *ec) + (EGLNativeDisplayType)output->surface, + output->surface, + gl_renderer->opaque_attribs, +- &format) < 0) { ++ &format, ++ 1) < 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 7c505ce..3f3394f 100644 +--- a/src/compositor-fbdev.c ++++ b/src/compositor-fbdev.c +@@ -570,7 +570,7 @@ fbdev_output_create(struct fbdev_compositor *compositor, + if (gl_renderer->output_create(&output->base, + (EGLNativeWindowType)NULL, NULL, + gl_renderer->opaque_attribs, +- NULL) < 0) { ++ NULL, 0) < 0) { + weston_log("gl_renderer_output_create failed.\n"); + goto out_shadow_surface; + } +@@ -871,7 +871,7 @@ fbdev_compositor_create(struct wl_display *display, int *argc, char *argv[], + if (gl_renderer->create(&compositor->base, NO_EGL_PLATFORM, + EGL_DEFAULT_DISPLAY, + gl_renderer->opaque_attribs, +- NULL) < 0) { ++ NULL, 0) < 0) { + weston_log("gl_renderer_create failed.\n"); + goto out_launcher; + } +diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c +index 303151c..c9983e0 100644 +--- a/src/compositor-wayland.c ++++ b/src/compositor-wayland.c +@@ -648,7 +648,8 @@ wayland_output_init_gl_renderer(struct wayland_output *output) + output->gl.egl_window, + output->gl.egl_window, + gl_renderer->alpha_attribs, +- NULL) < 0) ++ NULL, ++ 0) < 0) + goto cleanup_window; + + return 0; +@@ -1970,10 +1971,11 @@ wayland_compositor_create(struct wl_display *display, int use_pixman, + + if (!c->use_pixman) { + if (gl_renderer->create(&c->base, +- EGL_PLATFORM_WAYLAND_KHR, +- c->parent.wl_display, +- gl_renderer->alpha_attribs, +- NULL) < 0) { ++ EGL_PLATFORM_WAYLAND_KHR, ++ c->parent.wl_display, ++ gl_renderer->alpha_attribs, ++ NULL, ++ 0) < 0) { + weston_log("Failed to initialize the GL renderer; " + "falling back to pixman.\n"); + c->use_pixman = 1; +diff --git a/src/compositor-x11.c b/src/compositor-x11.c +index 5129e85..3565677 100644 +--- a/src/compositor-x11.c ++++ b/src/compositor-x11.c +@@ -906,7 +906,8 @@ x11_compositor_create_output(struct x11_compositor *c, int x, int y, + (EGLNativeWindowType) output->window, + &xid, + gl_renderer->opaque_attribs, +- NULL); ++ NULL, ++ 0); + if (ret < 0) + return NULL; + } +@@ -1493,7 +1494,7 @@ init_gl_renderer(struct x11_compositor *c) + return -1; + + ret = gl_renderer->create(&c->base, EGL_PLATFORM_X11_KHR, (void *) c->dpy, +- gl_renderer->opaque_attribs, NULL); ++ gl_renderer->opaque_attribs, NULL, 0); + + return ret; + } +diff --git a/src/gl-renderer.c b/src/gl-renderer.c +index ae3122f..248c8aa 100644 +--- a/src/gl-renderer.c ++++ b/src/gl-renderer.c +@@ -1898,14 +1898,38 @@ log_egl_config_info(EGLDisplay egldpy, EGLConfig eglconfig) + } + + static int ++match_config_to_visual(EGLDisplay egl_display, ++ EGLint visual_id, ++ EGLConfig *configs, ++ int count) ++{ ++ int i; ++ ++ for (i = 0; i < count; ++i) { ++ EGLint id; ++ ++ if (!eglGetConfigAttrib(egl_display, ++ configs[i], EGL_NATIVE_VISUAL_ID, ++ &id)) ++ continue; ++ ++ if (id == visual_id) ++ return i; ++ } ++ ++ weston_log("Unable to find an appropriate EGL config.\n"); ++ return -1; ++} ++ ++static int + egl_choose_config(struct gl_renderer *gr, const EGLint *attribs, +- const EGLint *visual_id, ++ const EGLint *visual_id, const int n_ids, + EGLConfig *config_out) + { + EGLint count = 0; + EGLint matched = 0; + EGLConfig *configs; +- int i; ++ int i, config_index = -1; + + if (!eglGetConfigs(gr->egl_display, NULL, 0, &count) || count < 1) + return -1; +@@ -1915,31 +1939,27 @@ egl_choose_config(struct gl_renderer *gr, const EGLint *attribs, + return -1; + + if (!eglChooseConfig(gr->egl_display, attribs, configs, +- count, &matched)) ++ count, &matched) || !matched) + goto out; + +- for (i = 0; i < matched; ++i) { +- EGLint id; ++ if (!visual_id) ++ config_index = 0; + +- if (visual_id) { +- if (!eglGetConfigAttrib(gr->egl_display, +- configs[i], EGL_NATIVE_VISUAL_ID, +- &id)) +- continue; ++ for (i = 0; config_index == -1 && i < n_ids; i++) ++ config_index = match_config_to_visual(gr->egl_display, ++ visual_id[i], ++ configs, ++ matched); + +- if (id != 0 && id != *visual_id) +- continue; +- } +- +- *config_out = configs[i]; +- +- free(configs); +- return 0; +- } ++ if (config_index != -1) ++ *config_out = configs[config_index]; + + out: + free(configs); +- return -1; ++ if (config_index == -1) ++ return -1; ++ ++ return 0; + } + + static void +@@ -1976,7 +1996,8 @@ gl_renderer_output_create(struct weston_output *output, + EGLNativeWindowType window_for_legacy, + void *window_for_platform, + const EGLint *attribs, +- const EGLint *visual_id) ++ const EGLint *visual_id, ++ int n_ids) + { + struct weston_compositor *ec = output->compositor; + struct gl_renderer *gr = get_renderer(ec); +@@ -1984,7 +2005,8 @@ gl_renderer_output_create(struct weston_output *output, + EGLConfig egl_config; + int i; + +- if (egl_choose_config(gr, attribs, visual_id, &egl_config) == -1) { ++ if (egl_choose_config(gr, attribs, visual_id, ++ n_ids, &egl_config) == -1) { + weston_log("failed to choose EGL config for output\n"); + return -1; + } +@@ -2260,7 +2282,7 @@ platform_to_extension(EGLenum platform) + static int + gl_renderer_create(struct weston_compositor *ec, EGLenum platform, + void *native_window, const EGLint *attribs, +- const EGLint *visual_id) ++ const EGLint *visual_id, int n_ids) + { + struct gl_renderer *gr; + EGLint major, minor; +@@ -2323,7 +2345,8 @@ gl_renderer_create(struct weston_compositor *ec, EGLenum platform, + goto err_egl; + } + +- if (egl_choose_config(gr, attribs, visual_id, &gr->egl_config) < 0) { ++ if (egl_choose_config(gr, attribs, visual_id, ++ n_ids, &gr->egl_config) < 0) { + weston_log("failed to choose EGL config\n"); + goto err_egl; + } +diff --git a/src/gl-renderer.h b/src/gl-renderer.h +index ebc139f..ceb4206 100644 +--- a/src/gl-renderer.h ++++ b/src/gl-renderer.h +@@ -76,7 +76,8 @@ struct gl_renderer_interface { + EGLenum platform, + void *native_window, + const EGLint *attribs, +- const EGLint *visual_id); ++ const EGLint *visual_id, ++ const int n_ids); + + EGLDisplay (*display)(struct weston_compositor *ec); + +@@ -84,7 +85,8 @@ struct gl_renderer_interface { + EGLNativeWindowType window_for_legacy, + void *window_for_platform, + const EGLint *attribs, +- const EGLint *visual_id); ++ const EGLint *visual_id, ++ const int n_ids); + + void (*output_destroy)(struct weston_output *output); + +-- +2.4.1 + diff --git a/0002-compositor-drm-pass-ARGB-fallback-to-gl-create-funct.patch b/0002-compositor-drm-pass-ARGB-fallback-to-gl-create-funct.patch new file mode 100644 index 0000000..c96943a --- /dev/null +++ b/0002-compositor-drm-pass-ARGB-fallback-to-gl-create-funct.patch @@ -0,0 +1,138 @@ +From c4cfe85d3af007e9fa30f10d10fa502ca1336fa6 Mon Sep 17 00:00:00 2001 +From: Derek Foreman +Date: Fri, 15 May 2015 12:12:40 -0500 +Subject: [PATCH 2/2] compositor-drm: pass ARGB fallback to gl create functions + for XRGB formats + +If the GL implementation doesn't provide an XRGB visual we may still be +able to proceed with an ARGB one. Since we're not changing the scanout +buffer format, and our current rendering loop always results in saturated +alpha in the frame buffer, it should be Just Fine(tm) - and probably better +than just exiting. + +This is a workaround for https://bugs.freedesktop.org/show_bug.cgi?id=89689 + +Reviewed-By: Bryce Harrington +Tested-By: Pekka Paalanen +Reviewed-By: Pekka Paalanen +Signed-off-by: Derek Foreman +--- + src/compositor-drm.c | 57 +++++++++++++++++++++++++++++++++++++++++++--------- + src/gl-renderer.c | 8 ++++++++ + 2 files changed, 55 insertions(+), 10 deletions(-) + +diff --git a/src/compositor-drm.c b/src/compositor-drm.c +index 69bdcfd..313860b 100644 +--- a/src/compositor-drm.c ++++ b/src/compositor-drm.c +@@ -1391,14 +1391,46 @@ create_gbm_device(int fd) + return gbm; + } + ++/* When initializing EGL, if the preferred buffer format isn't availble ++ * we may be able to susbstitute an ARGB format for an XRGB one. ++ * ++ * This returns 0 if substitution isn't possible, but 0 might be a ++ * legitimate format for other EGL platforms, so the caller is ++ * responsible for checking for 0 before calling gl_renderer->create(). ++ * ++ * This works around https://bugs.freedesktop.org/show_bug.cgi?id=89689 ++ * but it's entirely possible we'll see this again on other implementations. ++ */ + static int +-drm_compositor_create_gl_renderer(struct drm_compositor *ec) ++fallback_format_for(uint32_t format) + { +- EGLint format; ++ switch (format) { ++ case GBM_FORMAT_XRGB8888: ++ return GBM_FORMAT_ARGB8888; ++ case GBM_FORMAT_XRGB2101010: ++ return GBM_FORMAT_ARGB2101010; ++ default: ++ return 0; ++ } ++} + +- format = ec->format; +- if (gl_renderer->create(&ec->base, EGL_PLATFORM_GBM_KHR, (void *) ec->gbm, +- gl_renderer->opaque_attribs, &format, 1) < 0) { ++static int ++drm_compositor_create_gl_renderer(struct drm_compositor *ec) ++{ ++ EGLint format[2] = { ++ ec->format, ++ fallback_format_for(ec->format), ++ }; ++ int n_formats = 1; ++ ++ if (format[1]) ++ n_formats = 2; ++ if (gl_renderer->create(&ec->base, ++ EGL_PLATFORM_GBM_KHR, ++ (void *)ec->gbm, ++ gl_renderer->opaque_attribs, ++ format, ++ n_formats) < 0) { + return -1; + } + +@@ -1602,13 +1634,16 @@ find_crtc_for_connector(struct drm_compositor *ec, + static int + drm_output_init_egl(struct drm_output *output, struct drm_compositor *ec) + { +- EGLint format = output->format; +- int i, flags; ++ EGLint format[2] = { ++ output->format, ++ fallback_format_for(output->format), ++ }; ++ int i, flags, n_formats = 1; + + output->surface = gbm_surface_create(ec->gbm, + output->base.current_mode->width, + output->base.current_mode->height, +- format, ++ format[0], + GBM_BO_USE_SCANOUT | + GBM_BO_USE_RENDERING); + if (!output->surface) { +@@ -1616,12 +1651,14 @@ drm_output_init_egl(struct drm_output *output, struct drm_compositor *ec) + return -1; + } + ++ if (format[1]) ++ n_formats = 2; + if (gl_renderer->output_create(&output->base, + (EGLNativeDisplayType)output->surface, + output->surface, + gl_renderer->opaque_attribs, +- &format, +- 1) < 0) { ++ format, ++ n_formats) < 0) { + weston_log("failed to create gl renderer output state\n"); + gbm_surface_destroy(output->surface); + return -1; +diff --git a/src/gl-renderer.c b/src/gl-renderer.c +index 248c8aa..772c6a8 100644 +--- a/src/gl-renderer.c ++++ b/src/gl-renderer.c +@@ -934,6 +934,14 @@ output_rotate_damage(struct weston_output *output, + go->border_damage[go->buffer_damage_index] = border_status; + } + ++/* NOTE: We now allow falling back to ARGB gl visuals when XRGB is ++ * unavailable, so we're assuming the background has no transparency ++ * and that everything with a blend, like drop shadows, will have something ++ * opaque (like the background) drawn underneath it. ++ * ++ * Depending on the underlying hardware, violating that assumption could ++ * result in seeing through to another display plane. ++ */ + static void + gl_renderer_repaint_output(struct weston_output *output, + pixman_region32_t *output_damage) +-- +2.4.1 + diff --git a/weston.spec b/weston.spec index e478953..88f412e 100644 --- a/weston.spec +++ b/weston.spec @@ -5,9 +5,9 @@ %endif Name: weston -Version: 1.7.0 +Version: 1.7.92 #Release: 4%{?alphatag}%{?dist} -Release: 2%{?dist} +Release: 1%{?dist} Summary: Reference compositor for Wayland Group: User Interface/X License: BSD and CC-BY-SA @@ -22,6 +22,9 @@ Source1: make-git-snapshot.sh #Patch01: 0001-libinput-device-use-the-new-merged-scroll-events.patch #Patch02: 0001-libinput-device-use-the-discrete-axis-value-for-whee.patch +Patch1: 0001-gl-renderer-Take-a-list-of-acceptable-formats-in-cre.patch +Patch2: 0002-compositor-drm-pass-ARGB-fallback-to-gl-create-funct.patch + BuildRequires: autoconf BuildRequires: cairo-devel >= 1.10.0 BuildRequires: glib2-devel @@ -77,8 +80,8 @@ Common headers for weston %prep %setup -q -n %{name}-%{?gitdate:%{gitdate}}%{!?gitdate:%{version}} -#%patch01 -p1 -#%patch02 -p1 +%patch1 -p1 +%patch2 -p1 %build # temporary force to pick up configure.ac changes @@ -134,11 +137,16 @@ find $RPM_BUILD_ROOT -name \*.la | xargs rm -f %{_includedir}/weston/config-parser.h %{_includedir}/weston/timeline-object.h %{_includedir}/weston/matrix.h +%{_includedir}/weston/platform.h %{_includedir}/weston/version.h %{_includedir}/weston/zalloc.h %{_libdir}/pkgconfig/weston.pc %changelog +* Tue May 26 2015 Adam Jackson 1.7.92-1 +- weston 1.7.92 +- Backport patches to fall back to argb buffer if no xrgb is available + * Tue Mar 10 2015 Peter Hutterer - 1.7.0-2 - Rebuild for libinput soname bump