[Mesa-dev] [PATCH 2/3] egl_dri2: add support for Android
Chad Versace
chad at chad-versace.us
Thu Aug 25 13:09:18 PDT 2011
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.
>
> 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
More information about the mesa-dev
mailing list