<div dir="ltr">I don't know if the "alloca" change is a good idea. Some people consider it <a href="http://stackoverflow.com/questions/1018853/why-is-alloca-not-considered-good-practice">bad practice</a>, and looks like it's not used anywhere in wayland/weston code - but someone else should make that call.<div><br></div><div>Otherwise, though, looks good.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, May 5, 2015 at 2:22 PM, Derek Foreman <span dir="ltr"><<a href="mailto:derekf@osg.samsung.com" target="_blank">derekf@osg.samsung.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">Recent versions of Mesa have stopped exposing XRGB visuals for gl on<br>
some Intel GPUs.  While this may be changed in Mesa eventually, it's<br>
not impossible that some other hardware in the future won't provide<br>
XRGB visuals either.<br>
<br>
Let's try again with an ARGB visual if XRGB is unavailable.  Since<br>
we're not changing the scanout buffer format, and our current<br>
rendering loop always results in saturated alpha in the frame buffer,<br>
it should be Just Fine(tm) - and probably better than just exiting.<br>
<br>
Signed-off-by: Derek Foreman <<a href="mailto:derekf@osg.samsung.com">derekf@osg.samsung.com</a>><br>
---<br>
<br>
</span>Dima Ryazanov called me out for fallback_format() not working on all endians,<br>
and I've reworked the loop to be a single loop instead of two, similar to<br>
Daniel's suggestion (but still keeping the NULL visual_id means "give me the<br>
first match" semantic of the original)<br>
<br>
I've also replaced calloc with aloca so I don't have to worry about freeing<br>
the array on return, which simplifies things a little bit.  I didn't bother<br>
zeroing out the array, since it's filled in by eglChooseConfig.<br>
<br>
It's still an ugly function. :)<br>
<br>
 src/gl-renderer.c | 57 +++++++++++++++++++++++++++++++++++++++++--------------<br>
 1 file changed, 43 insertions(+), 14 deletions(-)<br>
<br>
diff --git a/src/gl-renderer.c b/src/gl-renderer.c<br>
index ae3122f..a4fd3a0 100644<br>
<span class="">--- a/src/gl-renderer.c<br>
+++ b/src/gl-renderer.c<br>
@@ -934,6 +934,14 @@ output_rotate_damage(struct weston_output *output,<br>
        go->border_damage[go->buffer_damage_index] = border_status;<br>
 }<br>
<br>
+/* NOTE: We now allow falling back to ARGB  gl visual ids when XRGB is<br>
+ * unavailable, so we're assuming the background has no transparency<br>
+ * and that everything with a blend, like drop shadows, will have something<br>
+ * opaque (like the background) drawn underneath it.<br>
+ *<br>
+ * Depending on the underlying hardware, violating that assumption could<br>
+ * result in seeing through to another display plane.<br>
+ */<br>
 static void<br>
 gl_renderer_repaint_output(struct weston_output *output,<br>
                              pixman_region32_t *output_damage)<br>
</span>@@ -1897,6 +1905,15 @@ log_egl_config_info(EGLDisplay egldpy, EGLConfig eglconfig)<br>
                weston_log_continue(" unknown\n");<br>
 }<br>
<br>
+static EGLint<br>
+fallback_format(EGLint format)<br>
+{<br>
+       if ((format & 0xFF) != 'X')<br>
+               return 0;<br>
+<br>
+       return (format & 0xFFFFFF00) | 'A';<br>
<span class="">+}<br>
+<br>
 static int<br>
 egl_choose_config(struct gl_renderer *gr, const EGLint *attribs,<br>
                  const EGLint *visual_id,<br>
</span>@@ -1904,41 +1921,53 @@ egl_choose_config(struct gl_renderer *gr, const EGLint *attribs,<br>
<span class=""> {<br>
        EGLint count = 0;<br>
        EGLint matched = 0;<br>
+       EGLint fallback_id;<br>
        EGLConfig *configs;<br>
</span>+       EGLConfig fallback_config = 0;<br>
        int i;<br>
<br>
        if (!eglGetConfigs(gr->egl_display, NULL, 0, &count) || count < 1)<br>
                return -1;<br>
<br>
-       configs = calloc(count, sizeof *configs);<br>
+       configs = alloca(count * sizeof *configs);<br>
        if (!configs)<br>
                return -1;<br>
<br>
        if (!eglChooseConfig(gr->egl_display, attribs, configs,<br>
                              count, &matched))<br>
-               goto out;<br>
+               return -1;<br>
+<br>
+       if (!matched)<br>
+               return -1;<br>
<br>
+       if (!visual_id) {<br>
+               *config_out = configs[0];<br>
<span class="">+               return 0;<br>
+       }<br>
+<br>
</span>+       fallback_id = fallback_format(*visual_id);<br>
        for (i = 0; i < matched; ++i) {<br>
                EGLint id;<br>
<br>
-               if (visual_id) {<br>
-                       if (!eglGetConfigAttrib(gr->egl_display,<br>
-                                       configs[i], EGL_NATIVE_VISUAL_ID,<br>
-                                       &id))<br>
-                               continue;<br>
<span class="">+               if (!eglGetConfigAttrib(gr->egl_display,<br>
+                               configs[i], EGL_NATIVE_VISUAL_ID,<br>
+                               &id))<br>
+                       continue;<br>
<br>
</span>-                       if (id != 0 && id != *visual_id)<br>
-                               continue;<br>
+               if (id == *visual_id) {<br>
<span class="">+                       *config_out = configs[i];<br>
</span>+                       return 0;<br>
                }<br>
+               if (id == fallback_id)<br>
+                       fallback_config = configs[i];<br>
+       }<br>
<br>
-               *config_out = configs[i];<br>
-<br>
-               free(configs);<br>
+       if (fallback_config) {<br>
+               weston_log("Falling back to ARGB visual\n");<br>
+               *config_out = fallback_config;<br>
                return 0;<br>
        }<br>
<br>
-out:<br>
-       free(configs);<br>
        return -1;<br>
 }<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
2.1.4<br>
<br>
</font></span></blockquote></div><br></div>