[Mesa-dev] [PATCH 2/3] egl_dri2: add support for Android

Chia-I Wu olvaffe at gmail.com
Thu Aug 25 20:14:06 PDT 2011


On Fri, Aug 26, 2011 at 4:09 AM, Chad Versace <chad at chad-versace.us> wrote:
> On 08/24/2011 06:20 PM, Chia-I Wu wrote:
>> On Thu, Aug 25, 2011 at 8:58 AM, Chad Versace <chad at chad-versace.us> wrote:
>> Comments below.
>>
>> On 08/23/2011 08:10 PM, Chia-I Wu wrote:
>>>>> Add platform_android.c that supports _EGL_PLAFORM_ANDROID.  It works
>>>>> with drm_gralloc, where back buffers of windows are backed by GEM
>>>>> objects.
>>>>>
>>>>> In Android a native window has a queue of back buffers allocated by the
>>>>> server, through drm_gralloc.  For each frame, EGL needs to
>>>>>
>>>>>   dequeue the next back buffer
>>>>>   render to the buffer
>>>>>   enqueue the buffer
>>>>>
>>>>> After enqueuing, the buffer is no longer valid to EGL.  A window has no
>>>>> depth buffer or other aux buffers.  They need to be allocated locally by
>>>>> EGL.
>>>>> ---
>>>>>  src/egl/drivers/dri2/egl_dri2.c         |   89 +++++
>>>>>  src/egl/drivers/dri2/egl_dri2.h         |   18 +
>>>>>  src/egl/drivers/dri2/platform_android.c |  588 +++++++++++++++++++++++++++++++
>>>>>  3 files changed, 695 insertions(+), 0 deletions(-)
>>>>>  create mode 100644 src/egl/drivers/dri2/platform_android.c
>>>>>
>>>>> diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
>>>>> index ba728a1..33c2330 100644
>>>>> --- a/src/egl/drivers/dri2/egl_dri2.c
>>>>> +++ b/src/egl/drivers/dri2/egl_dri2.c
>>
>> [snip]
>>
>>>>> +static _EGLImage *
>>>>> +dri2_create_image_android_native_buffer(_EGLDisplay *disp,
>>>>> +                                        EGLClientBuffer buffer)
>>
>> To reiterate Benjamin, I think dri2_create_image_android_native_buffer should go
>> in android_platform.c.
>>
>> [snip]
>>
>>>>> diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
>>>>> new file mode 100644
>>>>> index 0000000..d0de94c
>>>>> --- /dev/null
>>>>> +++ b/src/egl/drivers/dri2/platform_android.c
>>
>> [snip]
>>
>>>>> +static _EGLSurface *
>>>>> +droid_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
>>>>> +                 _EGLConfig *conf, EGLNativeWindowType window,
>>>>> +                 const EGLint *attrib_list)
>>>>> +{
>>>>> +   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
>>>>> +   struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
>>>>> +   struct dri2_egl_surface *dri2_surf;
>>>>> +   int format;
>>>>> +
>>>>> +   (void) drv;
>>>>> +
>>>>> +   if (!window || window->common.magic != ANDROID_NATIVE_WINDOW_MAGIC) {
>>>>> +      _eglError(EGL_BAD_NATIVE_WINDOW, "droid_create_surface");
>>>>> +      return NULL;
>>>>> +   }
>>>>> +   if (window->query(window, NATIVE_WINDOW_FORMAT, &format)) {
>>>>> +      _eglError(EGL_BAD_NATIVE_WINDOW, "droid_create_surface");
>>>>> +      return NULL;
>>>>> +   }
>>>>> +   if (format != dri2_conf->base.NativeVisualID) {
>>>>> +      _eglLog(_EGL_WARNING, "Native format mismatch: 0x%x != 0x%x",
>>>>> +            format, dri2_conf->base.NativeVisualID);
>>>>> +   }
>>>>> +
>>>>> +   dri2_surf = calloc(1, sizeof *dri2_surf);
>>>>> +   if (!dri2_surf) {
>>>>> +      _eglError(EGL_BAD_ALLOC, "droid_create_surface");
>>>>> +      return NULL;
>>>>> +   }
>>>>> +
>>>>> +   if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list))
>>>>> +      goto cleanup_surf;
>>
>> It seems that droid_get_buffers_with_format() only supports single-buffered
>> surfaces. So eglCreateWindowSurface should reject requests for which
>> EGL_RENDER_BUFFER != EGL_SINGLE_BUFFER.
>>
>>      if (dri2_surf->base.RenderBuffer != EGL_SINGLE_BUFFER)
>>         goto cleanup_surf;
>>> [CC Benjamin]
>>> EGL_RENDER_BUFFER is a hint here.  It is fine if the native window
>>> does not support EGL_SINGLE_BUFFER.
>
>
> You're right, specifying EGL_RENDER_BUFFER in eglCreateWindowSurface is just
> a hint. And since the spec says this about eglQuerySurface,
>    Querying EGL_RENDER_BUFFER returns the buffer which client API rendering
>    is requested to use. For a window surface, this is the same attribute value specified
>    when the surface was created.
> we shouldn't alter the requested value of dri2_surf->base.RenderBuffer.
>
>>> On the other hand, ctx->WindowRenderBuffer should be set.  It is
>>> queried by eglQueryContext.  I think it can be set in
>>> dri2_create_context: to EGL_BACK_BUFFER when there is
>>> dri_double_config and EGL_SINGLE_BUFFER when there is only
>>> dri_single_config.  Idea?
>
> I agree that it seems safe to set ctx->WindowRenderBuffer when there is only a
> dri_single_config. So, to ensure that the EGLConfig passed to
> eglCreateContext does not have a dri_double_config, I think you need
> to add this snippet in droid_add_configs_for_visuals:
>   for (i = 0; visuals[i].format; i++) {
>      ...
>      for (j = 0; dri2_dpy->driver_configs[j]; j++) {
>         ...
>         /* Maybe this? */
>         if (dri2_dpy->driver_configs[j]->modes.doubleBufferMode)
>            continue;
>         /* end suggestion */
>
>         dri2_conf = dri2_add_config(dpy, dri2_dpy->driver_configs[j],
>               count + 1, visuals[i].size, EGL_WINDOW_BIT, NULL,
>               visuals[i].rgba_masks);
> Also, the call to dri2_dpy->dri2->createNewDrawable should be passed
> dri2_conf->dri_single_config.
>
> But I am hesitant to set it to EGL_BACK_BUFFER when there is a
> dri2_double_config. If the driver supports rendering to a single buffered
> surface under a context that supports double-buffering, then, if we had set
> ctx->WindowRenderBuffer = EGL_BACK_BUFFER, that would force
> eglQueryContext(EGL_RENDER_BUFFER) to always return EGL_BACK_BUFFER, even
> when rendering to the single buffered surface.
A client can only see the back buffer(s) on Android.  There is no
single-buffered surface on Android.  In that case, reporting
EGL_SINGLE_BUFFER means we have to lie about a front buffer and make
glFlush/glFinish imply eglSwapBuffers.  And out of nowhere, the EGL
spec says that OpenGL ES does not support EGL_SINGLE_BUFFER for window
surfaces...

I think this is one of the gray areas that hasn't been sorted out yet.
 OpenGL requires a front buffer and GL_DRAW_BUFFER is a GL state that
EGL (or GLX) cannot change.  It is not clear how
eglQueryContext(EGL_RENDER_BUFFER) and glDrawBuffer() interact.  On
the other hand, OpenGL ES does not require a front buffer and there is
no GL_DRAW_BUFFER so EGL has EGL_RENDER_BUFFER to make up for it.
Take these into considerations, this issue may be too much for this
series to resolve.

>>
>> I think the DRI2 surface type needs to be set here too.
>>
>>      dri2_surf->type = DRI2_WINDOW_SURFACE;
>>> This field seems to be used by wayland only.  For the other places,
>>> dri2_surf->Base.Type is used.
>>>>> +
>>>>> +   dri2_surf->dri_drawable =
>>>>> +      (*dri2_dpy->dri2->createNewDrawable)(dri2_dpy->dri_screen,
>>>>> +                                        dri2_conf->dri_double_config,
>                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
> I think dri2_conf->dri_single_config should be passed here.
>
>>>>> +                                           dri2_surf);
>>>>> +   if (dri2_surf->dri_drawable == NULL) {
>>>>> +      _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable");
>>>>> +      goto cleanup_surf;
>>>>> +   }
>>>>> +
>>>>> +   window->common.incRef(&window->common);
>>>>> +   window->query(window, NATIVE_WINDOW_WIDTH, &dri2_surf->base.Width);
>>>>> +   window->query(window, NATIVE_WINDOW_HEIGHT, &dri2_surf->base.Height);
>>>>> +
>>>>> +   dri2_surf->window = window;
>>>>> +
>>>>> +   return &dri2_surf->base;
>>>>> +
>>>>> +cleanup_surf:
>>>>> +   free(dri2_surf);
>>>>> +
>>>>> +   return NULL;
>>>>> +}
>>
>> [snip]
>>
>>>>> +#include <xf86drm.h>
>>>>> +/* for i915 */
>>>>> +#include <i915_drm.h>
>>>>> +/* for radeon */
>>>>> +#include <radeon_drm.h>
>>
>> These includes should be moved to the top of the file.
>>> Will do and mention that they are only used by droid_get_pci_id.
>>>
>>
>>
>>
>
> --
> Chad Versace
> chad at chad-versace.us
>



-- 
olv at LunarG.com


More information about the mesa-dev mailing list