[PATCH weston v2] gl-renderer: If an XRGB format is requested but unavailable, try ARGB
Derek Foreman
derekf at osg.samsung.com
Mon May 11 12:31:29 PDT 2015
On 11/05/15 08:57 AM, Pekka Paalanen wrote:
> On Tue, 5 May 2015 16:22:22 -0500
> Derek Foreman <derekf at osg.samsung.com> wrote:
>
>> Recent versions of Mesa have stopped exposing XRGB visuals for gl on
>> some Intel GPUs. While this may be changed in Mesa eventually, it's
>> not impossible that some other hardware in the future won't provide
>> XRGB visuals either.
>>
>> Let's try again with an ARGB visual if XRGB is unavailable. 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.
>>
>> Signed-off-by: Derek Foreman <derekf at osg.samsung.com>
>> ---
>>
>> Dima Ryazanov called me out for fallback_format() not working on all endians,
>> and I've reworked the loop to be a single loop instead of two, similar to
>> Daniel's suggestion (but still keeping the NULL visual_id means "give me the
>> first match" semantic of the original)
>>
>> I've also replaced calloc with aloca so I don't have to worry about freeing
>> the array on return, which simplifies things a little bit. I didn't bother
>> zeroing out the array, since it's filled in by eglChooseConfig.
>>
>> It's still an ugly function. :)
>>
>> src/gl-renderer.c | 57 +++++++++++++++++++++++++++++++++++++++++--------------
>> 1 file changed, 43 insertions(+), 14 deletions(-)
>>
>> diff --git a/src/gl-renderer.c b/src/gl-renderer.c
>> index ae3122f..a4fd3a0 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 visual ids 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)
>> @@ -1897,6 +1905,15 @@ log_egl_config_info(EGLDisplay egldpy, EGLConfig eglconfig)
>> weston_log_continue(" unknown\n");
>> }
>>
>> +static EGLint
>> +fallback_format(EGLint format)
>> +{
>> + if ((format & 0xFF) != 'X')
>> + return 0;
>> +
>> + return (format & 0xFFFFFF00) | 'A';
>> +}
>
> I read the function name, I read the code, and I repeat that 6 times
> before I figure out the right interpretation. That's pretty awesome. In
> a not fun way. :-P
>
> How about calling it get_fallback_format_for()?
>
> Are you sure this works for X11 Visuals too? Oh, but x11-backend
> doesn't pass any visual in, so that saves you.
>
> What about GBM visuals (drmfourccs) like RA24 or BA24? Oh, but this
> actually a GBM format code, which is hand-picked and cannot just
> whatever, so this works.
Really, only the drm backend even specifies a native visual id, and it's
limited to the formats we accept in weston.ini.
In any event, it does make more sense to push that complexity into
compositor-drm.c as the gl-renderer might be used by something that uses
something else for a native visual id...
> There's so much fun going on, that I'd like to have big comment
> explaining it all, please. :-)
>
> With all these assumptions around, you might as well just hardcode a
> switch-statement and say in comments where the funny numbers come from.
>
> Or, even better, extend the gl_renderer_create() API to have the
> fallback format passed in explicitly from the backend, which can then
> use the proper #defined names. Or go even further, if there is a list
> of acceptable visuals.
>
> It's a question of how far you want to go...
Ok, I've implemented it with a list of formats passed in from the
back-end and only the drm backend tries to do fallback now.
I've split it into two patches, one for the gl-renderer API change, one
for drm to use a fallback fourcc.
>> +
>> static int
>> egl_choose_config(struct gl_renderer *gr, const EGLint *attribs,
>> const EGLint *visual_id,
>> @@ -1904,41 +1921,53 @@ egl_choose_config(struct gl_renderer *gr, const EGLint *attribs,
>> {
>> EGLint count = 0;
>> EGLint matched = 0;
>> + EGLint fallback_id;
>> EGLConfig *configs;
>> + EGLConfig fallback_config = 0;
>> int i;
>>
>> if (!eglGetConfigs(gr->egl_display, NULL, 0, &count) || count < 1)
>> return -1;
>>
>> - configs = calloc(count, sizeof *configs);
>> + configs = alloca(count * sizeof *configs);
>
> The number of eglconfigs could be large, so maybe alloca isn't quite
> right here...
>
>> if (!configs)
>> return -1;
>
> Can't test this with alloca.
Ok, ok, I won't use alloca. :)
>>
>> if (!eglChooseConfig(gr->egl_display, attribs, configs,
>> count, &matched))
>> - goto out;
>> + return -1;
>> +
>> + if (!matched)
>> + return -1;
>>
>> + if (!visual_id) {
>> + *config_out = configs[0];
>> + return 0;
>> + }
>> +
>> + fallback_id = fallback_format(*visual_id);
>> 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 (!eglGetConfigAttrib(gr->egl_display,
>> + configs[i], EGL_NATIVE_VISUAL_ID,
>> + &id))
>> + continue;
>>
>> - if (id != 0 && id != *visual_id)
>> - continue;
>> + if (id == *visual_id) {
>> + *config_out = configs[i];
>> + return 0;
>> }
>> + if (id == fallback_id)
>> + fallback_config = configs[i];
>> + }
>
> Hmm, but if we end up with the fallback_config, we will get the last
> config that matches fallback. Usually we prefer the first config that
> matches. Would it make sense to use the first fallback-matching config
> in that case?
Addressed in the follow up.
>>
>> - *config_out = configs[i];
>> -
>> - free(configs);
>> + if (fallback_config) {
>> + weston_log("Falling back to ARGB visual\n");
>> + *config_out = fallback_config;
>> return 0;
>> }
>>
>> -out:
>> - free(configs);
>> return -1;
>> }
>>
>
> Thanks,
> pq
>
More information about the wayland-devel
mailing list