[Mesa-dev] [PATCH] st/egl: Prepare for EGL_ALPHA_FORMAT

Chia-I Wu olv at lunarg.com
Fri Sep 2 06:17:32 PDT 2011


On Fri, Sep 2, 2011 at 3:27 PM, Benjamin Franzke
<benjaminfranzke at googlemail.com> wrote:
> 2011/9/2 Chia-I Wu <olv at lunarg.com>:
>> On Thu, Sep 1, 2011 at 5:53 PM, Benjamin Franzke
>> <benjaminfranzke at googlemail.com> wrote:
>>> In preparation for wayland ALPHA_FORMAT usage,
>>> see commit 7b1d94e5d1f53ac5f59000176aea1d02fc9a1181.
>>>
>>> Changes:
>>>  - New native_config surface_type bit: alpha_format_pre_bit
>>>  - Introduction of native_surface_attribs
>>>   (as new parameter in create_{window,pixmap}_surface)
>>>  - New attrib alpha_format in native_surface_attribs
>> EGL_VG_ALPHA_FORMAT_PRE is supposed to only change the behavior of
>> st/vega.  It is suggested that the window system should not rely on
>> it.  I wonder if there are other (clean) ways do achieve the same
>> goal..
>
> Yes, this is kind of a strange thing in the eglspec, to have an
> attribute that shouldnt be relied on/used..?
>
> As EGL wants EGL_VG_ALPHA_FORMAT only for OpenVG, we probably need an
> extension or so.
> Kristian can give better information what he plans here.
>>
>> That said, I am thinking modeling it with
>>
>>  - Add "struct native_surface_present" and have
>>   native_surface::present() takes the surface and the struct as its
>>   arguments.  This is just a clean up step.
>>  - Add NATIVE_PARAM_USE_VG_ALPHA_FORMAT_PRE to the display parameter.
>>   When it is true, set EGL_VG_ALPHA_FORMAT_PRE_BIT for all configs.
>
> Sounds good in genral, but I wanted to expose EGL_VG_ALPHA_FORMAT_PRE_BIT
> only for configs which have an alpha format,
> this comes into account when talking about the following point:
>
>>   As st/vega does not support pre-multiplied alpha, EGL_OPENVG_BIT
>>   should be cleared meanwhile.
>
> ...Thats abit of a problem, with that we couldnt use openvg with wayland,
> since all configs have EGL_OPENVG_BIT cleared (because of the previous point).
Yes, that is my understanding of EGL_VG_ALPHA_FORMAT_PRE.  It changes
what OpenVG writes to the surface (as its sole purpose).
EGL_VG_ALPHA_FORMAT_PRE_BIT and EGL_OPENVG_BIT conflict unless st/vega
is updated.
>>  - Add a boolean to native_surface_present to indicate the
>>   presented buffer should be treated as with pre-multiplied alpha or
>>   not.
>
> I'm not sure about that, dont we need to know about that attribute at
> surface creation time,
> to respect it when choosing a format that reflects that?
> My main problem here is that I dont know how to choose between
> premultiplied and non-premultiplied in gallium (thought this would be
> a new format?).
I am not sure if there should be formats with pre-multiplied alpha.
Being a format means, any access to a resource of such format will
automatically multiple the color components by alpha prior to write,
or divide by alpha prior to read.  That is not something exposed in
OpenGL, nor am I sure if any hardware supports that.

Prior to the recent removal of wl_visual.  Suppose an GL-based app
creates a wl_window with pre-mulitplied alpha RGBA, I think it is the
app's responsibility to pre-multiply color components by alpha in its
fragment shader.  The fact that the visual is pre-multiplied, to me,
is more like telling the compositor how to composite the surface.

>>
>> I've also attached a diff to native.h.
>>
>> The changes are based on the assumptions that
>>
>>  - The display server allows EGL to control how a presented buffer
>>   is composited: assuming premultiplied alpha or not.
>
> This is currently broken in wayland (due to the latest changes), but the idea is
> that the compositor knows whether a wl_buffer has premulitplied alpha or not.
IIRC, it works or can work like this

 - app requests for a format with pre-multiplied alpha
   (by setting alpha format to EGL_VG_ALPHA_FORMAT_PRE)
 - EGL creates pipe_resources with PIPE_FORMAT_B8G8R8A8_UNORM
 - app makes sure color components are multiplied by alpha prior to
   write (a manual step when GL is used)
 - When eglSwapBuffers is called, EGL creates wl_buffer with
   pre-multiplied alpha format for the pipe_resource and
   attach it to the wl_surface.

In this case, st/egl can determine whether a wl_buffer has
premultiplied alpha or not at eglSwapBuffers time.  Theoretically, It
can even change the format at any given time just like changing
EGL_SWAP_BEHAVIOR or eglSwalInterval.  But that cannot not exposed
with EGL_VG_ALPHA_FORMAT.

>>  - The display server expects EGL to expose the functionality through
>>   EGL_VG_ALPHA_FORMAT.
>
> The display server in general doesnt care how things are done client side,
> but in wayland+egl we currently try to expose buffer formats using EGLConfigs
> with the use of vendor specific wayland interfaces (wl_drm in the mesa case),
> that are implemented in egl (both client- and serverside).
> So yes.
>>
>> Are the assumptions true under wayland?  Thoughts?
>>
>>> CC: Chia-I Wu <olv at lunarg.com>
>>> ---
>>>  .../state_trackers/egl/android/native_android.cpp  |    3 ++-
>>>  src/gallium/state_trackers/egl/common/egl_g3d.c    |    3 +++
>>>  .../state_trackers/egl/common/egl_g3d_api.c        |   13 +++++++++++--
>>>  .../state_trackers/egl/common/egl_g3d_image.c      |    2 +-
>>>  src/gallium/state_trackers/egl/common/native.h     |   11 +++++++++--
>>>  .../state_trackers/egl/common/native_helper.c      |    2 +-
>>>  src/gallium/state_trackers/egl/drm/native_drm.c    |    3 ++-
>>>  src/gallium/state_trackers/egl/gdi/native_gdi.c    |    3 ++-
>>>  .../state_trackers/egl/wayland/native_wayland.c    |    6 ++++--
>>>  src/gallium/state_trackers/egl/x11/native_dri2.c   |    6 ++++--
>>>  src/gallium/state_trackers/egl/x11/native_ximage.c |    6 ++++--
>>>  11 files changed, 43 insertions(+), 15 deletions(-)
>>>
>>> diff --git a/src/gallium/state_trackers/egl/android/native_android.cpp b/src/gallium/state_trackers/egl/android/native_android.cpp
>>> index 338427d..e4a74b3 100644
>>> --- a/src/gallium/state_trackers/egl/android/native_android.cpp
>>> +++ b/src/gallium/state_trackers/egl/android/native_android.cpp
>>> @@ -494,7 +494,8 @@ android_surface_destroy(struct native_surface *nsurf)
>>>  static struct native_surface *
>>>  android_display_create_window_surface(struct native_display *ndpy,
>>>                                       EGLNativeWindowType win,
>>> -                                      const struct native_config *nconf)
>>> +                                      const struct native_config *nconf,
>>> +                                      const struct native_surface_attribs *attr)
>>>  {
>>>    struct android_display *adpy = android_display(ndpy);
>>>    struct android_config *aconf = android_config(nconf);
>>> diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
>>> index b5e3d99..233867b 100644
>>> --- a/src/gallium/state_trackers/egl/common/egl_g3d.c
>>> +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
>>> @@ -262,6 +262,9 @@ init_config_attributes(_EGLConfig *conf, const struct native_config *nconf,
>>>       surface_type |= EGL_PBUFFER_BIT;
>>>    }
>>>
>>> +   if (nconf->alpha_format_pre_bit)
>>> +      surface_type |= EGL_VG_ALPHA_FORMAT_PRE_BIT;
>>> +
>>>    conf->Conformant = api_mask;
>>>    conf->RenderableType = api_mask;
>>>
>>> diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_api.c b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
>>> index f897054..1b81e78 100644
>>> --- a/src/gallium/state_trackers/egl/common/egl_g3d_api.c
>>> +++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
>>> @@ -217,6 +217,13 @@ struct egl_g3d_create_surface_arg {
>>>    } u;
>>>  };
>>>
>>> +static void
>>> +egl_g3d_fill_surface_attribs(struct egl_g3d_surface *gsurf,
>>> +                             struct native_surface_attribs *attr)
>>> +{
>>> +   attr->alpha_format = gsurf->base.VGAlphaFormat;
>>> +}
>>> +
>>>  static _EGLSurface *
>>>  egl_g3d_create_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
>>>                        struct egl_g3d_create_surface_arg *arg,
>>> @@ -226,6 +233,7 @@ egl_g3d_create_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
>>>    struct egl_g3d_config *gconf = egl_g3d_config(conf);
>>>    struct egl_g3d_surface *gsurf;
>>>    struct native_surface *nsurf;
>>> +   struct native_surface_attribs nsurf_attr;
>>>    const char *err;
>>>
>>>    switch (arg->type) {
>>> @@ -255,16 +263,17 @@ egl_g3d_create_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
>>>       FREE(gsurf);
>>>       return NULL;
>>>    }
>>> +   egl_g3d_fill_surface_attribs(gsurf, &nsurf_attr);
>>>
>>>    /* create the native surface */
>>>    switch (arg->type) {
>>>    case EGL_WINDOW_BIT:
>>>       nsurf = gdpy->native->create_window_surface(gdpy->native,
>>> -            arg->u.win, gconf->native);
>>> +            arg->u.win, gconf->native, &nsurf_attr);
>>>       break;
>>>    case EGL_PIXMAP_BIT:
>>>       nsurf = gdpy->native->create_pixmap_surface(gdpy->native,
>>> -            arg->u.pix, gconf->native);
>>> +            arg->u.pix, gconf->native, &nsurf_attr);
>>>       break;
>>>  #ifdef EGL_MESA_screen_surface
>>>    case EGL_SCREEN_BIT_MESA:
>>> diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_image.c b/src/gallium/state_trackers/egl/common/egl_g3d_image.c
>>> index 4d90c40..6d3315a 100644
>>> --- a/src/gallium/state_trackers/egl/common/egl_g3d_image.c
>>> +++ b/src/gallium/state_trackers/egl/common/egl_g3d_image.c
>>> @@ -48,7 +48,7 @@ egl_g3d_reference_native_pixmap(_EGLDisplay *dpy, EGLNativePixmapType pix)
>>>    struct pipe_resource *textures[NUM_NATIVE_ATTACHMENTS];
>>>    enum native_attachment natt;
>>>
>>> -   nsurf = gdpy->native->create_pixmap_surface(gdpy->native, pix, NULL);
>>> +   nsurf = gdpy->native->create_pixmap_surface(gdpy->native, pix, NULL, NULL);
>>>    if (!nsurf)
>>>       return NULL;
>>>
>>> diff --git a/src/gallium/state_trackers/egl/common/native.h b/src/gallium/state_trackers/egl/common/native.h
>>> index 58593a4..5df8e7d 100644
>>> --- a/src/gallium/state_trackers/egl/common/native.h
>>> +++ b/src/gallium/state_trackers/egl/common/native.h
>>> @@ -111,6 +111,10 @@ struct native_surface {
>>>    void (*wait)(struct native_surface *nsurf);
>>>  };
>>>
>>> +struct native_surface_attribs {
>>> +   uint alpha_format;
>>> +};
>>> +
>>>  /**
>>>  * Describe a native display config.
>>>  */
>>> @@ -123,6 +127,7 @@ struct native_config {
>>>    boolean window_bit;
>>>    boolean pixmap_bit;
>>>    boolean scanout_bit;
>>> +   boolean alpha_format_pre_bit;
>>>
>>>    int native_visual_id;
>>>    int native_visual_type;
>>> @@ -196,7 +201,8 @@ struct native_display {
>>>     */
>>>    struct native_surface *(*create_window_surface)(struct native_display *ndpy,
>>>                                                    EGLNativeWindowType win,
>>> -                                                   const struct native_config *nconf);
>>> +                                                   const struct native_config *nconf,
>>> +                                                   const struct native_surface_attribs *attribs);
>>>
>>>    /**
>>>     * Create a pixmap surface.  The native config may be NULL.  In that case, a
>>> @@ -205,7 +211,8 @@ struct native_display {
>>>     */
>>>    struct native_surface *(*create_pixmap_surface)(struct native_display *ndpy,
>>>                                                    EGLNativePixmapType pix,
>>> -                                                   const struct native_config *nconf);
>>> +                                                   const struct native_config *nconf,
>>> +                                                   const struct native_surface_attribs *attribs);
>>>
>>>    const struct native_display_buffer *buffer;
>>>    const struct native_display_modeset *modeset;
>>> diff --git a/src/gallium/state_trackers/egl/common/native_helper.c b/src/gallium/state_trackers/egl/common/native_helper.c
>>> index cca1e1c..bea7635 100644
>>> --- a/src/gallium/state_trackers/egl/common/native_helper.c
>>> +++ b/src/gallium/state_trackers/egl/common/native_helper.c
>>> @@ -383,7 +383,7 @@ native_display_copy_to_pixmap(struct native_display *ndpy,
>>>    if (!pipe)
>>>       return FALSE;
>>>
>>> -   nsurf = ndpy->create_pixmap_surface(ndpy, pix, NULL);
>>> +   nsurf = ndpy->create_pixmap_surface(ndpy, pix, NULL, NULL);
>>>    if (!nsurf)
>>>       return FALSE;
>>>
>>> diff --git a/src/gallium/state_trackers/egl/drm/native_drm.c b/src/gallium/state_trackers/egl/drm/native_drm.c
>>> index c013769..0c4e496 100644
>>> --- a/src/gallium/state_trackers/egl/drm/native_drm.c
>>> +++ b/src/gallium/state_trackers/egl/drm/native_drm.c
>>> @@ -247,7 +247,8 @@ static struct native_display_wayland_bufmgr drm_display_wayland_bufmgr = {
>>>  static struct native_surface *
>>>  drm_create_pixmap_surface(struct native_display *ndpy,
>>>                               EGLNativePixmapType pix,
>>> -                              const struct native_config *nconf)
>>> +                              const struct native_config *nconf,
>>> +                              const struct native_surface_attribs *attr)
>>>  {
>>>    struct gbm_gallium_drm_bo *bo = (void *) pix;
>>>
>>> diff --git a/src/gallium/state_trackers/egl/gdi/native_gdi.c b/src/gallium/state_trackers/egl/gdi/native_gdi.c
>>> index 6bf0d4e..548d402 100644
>>> --- a/src/gallium/state_trackers/egl/gdi/native_gdi.c
>>> +++ b/src/gallium/state_trackers/egl/gdi/native_gdi.c
>>> @@ -229,7 +229,8 @@ gdi_surface_destroy(struct native_surface *nsurf)
>>>  static struct native_surface *
>>>  gdi_display_create_window_surface(struct native_display *ndpy,
>>>                                   EGLNativeWindowType win,
>>> -                                  const struct native_config *nconf)
>>> +                                  const struct native_config *nconf,
>>> +                                  const struct native_surface_attribs *attr)
>>>  {
>>>    struct gdi_display *gdpy = gdi_display(ndpy);
>>>    struct gdi_surface *gsurf;
>>> diff --git a/src/gallium/state_trackers/egl/wayland/native_wayland.c b/src/gallium/state_trackers/egl/wayland/native_wayland.c
>>> index 544d4be..548a340 100644
>>> --- a/src/gallium/state_trackers/egl/wayland/native_wayland.c
>>> +++ b/src/gallium/state_trackers/egl/wayland/native_wayland.c
>>> @@ -352,7 +352,8 @@ wayland_surface_destroy(struct native_surface *nsurf)
>>>  static struct native_surface *
>>>  wayland_create_pixmap_surface(struct native_display *ndpy,
>>>                               EGLNativePixmapType pix,
>>> -                              const struct native_config *nconf)
>>> +                              const struct native_config *nconf,
>>> +                              const struct native_surface_attribs *attr)
>>>  {
>>>    struct wayland_display *display = wayland_display(ndpy);
>>>    struct wayland_surface *surface;
>>> @@ -406,7 +407,8 @@ wayland_create_pixmap_surface(struct native_display *ndpy,
>>>  static struct native_surface *
>>>  wayland_create_window_surface(struct native_display *ndpy,
>>>                               EGLNativeWindowType win,
>>> -                              const struct native_config *nconf)
>>> +                              const struct native_config *nconf,
>>> +                              const struct native_surface_attribs *attr)
>>>  {
>>>    struct wayland_display *display = wayland_display(ndpy);
>>>    struct wayland_config *config = wayland_config(nconf);
>>> diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c
>>> index 4b8be7b..385810e 100644
>>> --- a/src/gallium/state_trackers/egl/x11/native_dri2.c
>>> +++ b/src/gallium/state_trackers/egl/x11/native_dri2.c
>>> @@ -475,7 +475,8 @@ dri2_display_create_surface(struct native_display *ndpy,
>>>  static struct native_surface *
>>>  dri2_display_create_window_surface(struct native_display *ndpy,
>>>                                    EGLNativeWindowType win,
>>> -                                   const struct native_config *nconf)
>>> +                                   const struct native_config *nconf,
>>> +                                   const struct native_surface_attribs *attr)
>>>  {
>>>    struct dri2_surface *dri2surf;
>>>
>>> @@ -487,7 +488,8 @@ dri2_display_create_window_surface(struct native_display *ndpy,
>>>  static struct native_surface *
>>>  dri2_display_create_pixmap_surface(struct native_display *ndpy,
>>>                                    EGLNativePixmapType pix,
>>> -                                   const struct native_config *nconf)
>>> +                                   const struct native_config *nconf,
>>> +                                   const struct native_surface_attribs *attr)
>>>  {
>>>    struct dri2_surface *dri2surf;
>>>
>>> diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c
>>> index e7794f0..e5cf860 100644
>>> --- a/src/gallium/state_trackers/egl/x11/native_ximage.c
>>> +++ b/src/gallium/state_trackers/egl/x11/native_ximage.c
>>> @@ -285,7 +285,8 @@ ximage_display_create_surface(struct native_display *ndpy,
>>>  static struct native_surface *
>>>  ximage_display_create_window_surface(struct native_display *ndpy,
>>>                                      EGLNativeWindowType win,
>>> -                                     const struct native_config *nconf)
>>> +                                     const struct native_config *nconf,
>>> +                                     const struct native_surface_attribs *attr)
>>>  {
>>>    struct ximage_surface *xsurf;
>>>
>>> @@ -323,7 +324,8 @@ get_pixmap_format(struct native_display *ndpy, EGLNativePixmapType pix)
>>>  static struct native_surface *
>>>  ximage_display_create_pixmap_surface(struct native_display *ndpy,
>>>                                      EGLNativePixmapType pix,
>>> -                                     const struct native_config *nconf)
>>> +                                     const struct native_config *nconf,
>>> +                                     const struct native_surface_attribs *attr)
>>>  {
>>>    struct ximage_surface *xsurf;
>>>
>>> --
>>> 1.7.3.4
>>>
>>>
>>
>>
>>
>> --
>> olv at LunarG.com
>>
>



-- 
olv at LunarG.com


More information about the mesa-dev mailing list