139 lines
4.5 KiB
Diff
139 lines
4.5 KiB
Diff
|
From c4cfe85d3af007e9fa30f10d10fa502ca1336fa6 Mon Sep 17 00:00:00 2001
|
||
|
From: Derek Foreman <derekf@osg.samsung.com>
|
||
|
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 <bryce@osg.samsung.com>
|
||
|
Tested-By: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
|
||
|
Reviewed-By: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
|
||
|
Signed-off-by: Derek Foreman <derekf@osg.samsung.com>
|
||
|
---
|
||
|
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
|
||
|
|