2011/8/24 Chia-I Wu <olva...@gmail.com>: > On Wed, Aug 24, 2011 at 7:01 PM, Benjamin Franzke > <benjaminfran...@googlemail.com> wrote: >> 2011/8/24 Chia-I Wu <olva...@gmail.com>: >>> 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 >>> @@ -577,6 +577,12 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp) >>> return dri2_initialize_wayland(drv, disp); >>> #endif >>> #endif >>> +#ifdef HAVE_ANDROID_PLATFORM >>> + case _EGL_PLATFORM_ANDROID: >>> + if (disp->Options.TestOnly) >>> + return EGL_TRUE; >>> + return dri2_initialize_android(drv, disp); >>> +#endif >>> >>> default: >>> return EGL_FALSE; >>> @@ -1083,6 +1089,81 @@ dri2_create_image_wayland_wl_buffer(_EGLDisplay >>> *disp, _EGLContext *ctx, >>> } >>> #endif >>> >>> +#ifdef HAVE_ANDROID_PLATFORM >>> + >>> +static _EGLImage * >>> +dri2_create_image_android_native_buffer(_EGLDisplay *disp, >>> + EGLClientBuffer buffer) >>> +{ >>> + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); >>> + struct android_native_buffer_t *buf = >>> + (struct android_native_buffer_t *) buffer; >>> + struct gralloc_drm_handle_t *handle; >>> + struct dri2_egl_image *dri2_img; >>> + EGLint format; >>> + >>> + if (!buf || buf->common.magic != ANDROID_NATIVE_BUFFER_MAGIC || >>> + buf->common.version != sizeof(*buf)) { >>> + _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR"); >>> + return NULL; >>> + } >>> + >>> + /* check that the buffer is allocated by drm_gralloc and cast */ >>> + handle = gralloc_drm_handle(buf->handle); >>> + if (!handle || !handle->name) { >>> + _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR"); >>> + return NULL; >>> + } >>> + >>> + switch (buf->format) { >>> + case HAL_PIXEL_FORMAT_BGRA_8888: >>> + format = __DRI_IMAGE_FORMAT_ARGB8888; >>> + break; >>> + case HAL_PIXEL_FORMAT_RGB_565: >>> + format = __DRI_IMAGE_FORMAT_RGB565; >> Hm, I saw this also in the st/egl code, but forgot to ask there, >> why is rgb565 reverse in comparison to the other native android formats? >> (This is more a question for st/egl/android/native_android.cpp, >> but both codes could probably use a comment?) > By convention, the channel order of __DRI_IMAGE_FORMAT_ is the > opposite of that of PIPE_FORMAT_. For example, > __DRI_IMAGE_FORMAT_RGB565 maps to PIPE_FORMAT_B5G6R5_UNORM.
Right, that wasnt my problem, rather what the HAL_PIXEL_FORMAT's mean (that they have different byte orders..). > > As for HAL_PIXEL_FORMAT_, there is no rule... The switch-statement in > st/egl defines what a HAL_PIXEL_FORMAT really means. As for egl_dri2 > here, I will add this comment > > /* see the table in droid_add_configs_for_visuals */ Yea, a reference to that table is good, since that really helps to understand the mapping. > >>> + break; >>> + case HAL_PIXEL_FORMAT_RGBA_8888: >>> + case HAL_PIXEL_FORMAT_RGBX_8888: >>> + case HAL_PIXEL_FORMAT_RGB_888: >>> + case HAL_PIXEL_FORMAT_RGBA_5551: >>> + case HAL_PIXEL_FORMAT_RGBA_4444: >>> + /* unsupported */ >>> + default: >>> + _eglLog(_EGL_WARNING, "unsupported native buffer format 0x%x", >>> buf->format); >>> + return NULL; >>> + break; >>> + } >>> + >>> + dri2_img = calloc(1, sizeof(*dri2_img)); >>> + if (!dri2_img) { >>> + _eglError(EGL_BAD_ALLOC, "droid_create_image_mesa_drm"); >>> + return NULL; >>> + } >>> + >>> + if (!_eglInitImage(&dri2_img->base, disp)) { >>> + free(dri2_img); >>> + return NULL; >>> + } >>> + >>> + dri2_img->dri_image = >>> + dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen, >>> + buf->width, >>> + buf->height, >>> + format, >>> + handle->name, >>> + buf->stride, >>> + dri2_img); >>> + if (!dri2_img->dri_image) { >>> + free(dri2_img); >>> + _eglError(EGL_BAD_ALLOC, "droid_create_image_mesa_drm"); >>> + return NULL; >>> + } >>> + >>> + return &dri2_img->base; >>> +} >>> + >>> +#endif /* HAVE_ANDROID_PLATFORM */ >>> + >> >> An image type specific to a platform should be only implemented (and >> available) >> in that platform, like its done for image-from-pixmap in the other platforms. > Yeah, I forgot EGL_WAYLAND_BUFFER_WL is cross-platform. Will move > this to platform_android.c. >>> _EGLImage * >>> dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp, >>> _EGLContext *ctx, EGLenum target, >>> @@ -1099,6 +1180,10 @@ dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay >>> *disp, >>> case EGL_WAYLAND_BUFFER_WL: >>> return dri2_create_image_wayland_wl_buffer(disp, ctx, buffer, >>> attr_list); >>> #endif >>> +#ifdef HAVE_ANDROID_PLATFORM >>> + case EGL_NATIVE_BUFFER_ANDROID: >>> + return dri2_create_image_android_native_buffer(disp, buffer); >>> +#endif >> >> With the previous comment, this would be part of a >> droid_create_image() in platform_android.c. > Will do. >>> default: >>> _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr"); >>> return EGL_NO_IMAGE_KHR; >>> @@ -1323,7 +1408,11 @@ dri2_load(_EGLDriver *drv) >>> { >>> struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); >>> #ifdef HAVE_SHARED_GLAPI >>> +#ifdef HAVE_ANDROID_PLATFORM >>> + const char *libname = "libglapi.so"; >>> +#else >>> const char *libname = "libglapi.so.0"; >>> +#endif >>> #else >>> /* >>> * Both libGL.so and libglapi.so are glapi providers. There is no way to >>> diff --git a/src/egl/drivers/dri2/egl_dri2.h >>> b/src/egl/drivers/dri2/egl_dri2.h >>> index be272f9..cebb0ba 100644 >>> --- a/src/egl/drivers/dri2/egl_dri2.h >>> +++ b/src/egl/drivers/dri2/egl_dri2.h >>> @@ -48,6 +48,14 @@ >>> #include <gbm_driint.h> >>> #endif >>> >>> +#ifdef HAVE_ANDROID_PLATFORM >>> +#define LOG_TAG "EGL-DRI2" >>> +#include <ui/egl/android_natives.h> >>> +#include <ui/android_native_buffer.h> >>> +#include <cutils/log.h> >>> +#include <gralloc_drm_handle.h> >>> +#endif >>> + >>> #include "eglconfig.h" >>> #include "eglcontext.h" >>> #include "egldisplay.h" >>> @@ -162,6 +170,13 @@ struct dri2_egl_surface >>> __DRIbuffer *pending_buffer; >>> EGLBoolean block_swap_buffers; >>> #endif >>> + >>> +#ifdef HAVE_ANDROID_PLATFORM >>> + android_native_window_t *window; >>> + android_native_buffer_t *buffer; >>> + >>> + __DRIbuffer *local_buffers[__DRI_BUFFER_COUNT]; >>> +#endif >>> }; >>> >>> struct dri2_egl_buffer { >>> @@ -225,6 +240,9 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp); >>> EGLBoolean >>> dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp); >>> >>> +EGLBoolean >>> +dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *disp); >>> + >>> char * >>> dri2_get_driver_for_fd(int fd); >>> char * >>> 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 >>> @@ -0,0 +1,588 @@ >>> +/* >>> + * Mesa 3-D graphics library >>> + * Version: 7.12 >>> + * >>> + * Copyright (C) 2010-2011 Chia-I Wu <olva...@gmail.com> >>> + * Copyright (C) 2010-2011 LunarG Inc. >>> + * >>> + * Based on platform_x11, which has >>> + * >>> + * Copyright © 2011 Intel Corporation >>> + * >>> + * Permission is hereby granted, free of charge, to any person obtaining a >>> + * copy of this software and associated documentation files (the >>> "Software"), >>> + * to deal in the Software without restriction, including without >>> limitation >>> + * the rights to use, copy, modify, merge, publish, distribute, sublicense, >>> + * and/or sell copies of the Software, and to permit persons to whom the >>> + * Software is furnished to do so, subject to the following conditions: >>> + * >>> + * The above copyright notice and this permission notice shall be included >>> + * in all copies or substantial portions of the Software. >>> + * >>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS >>> OR >>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, >>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL >>> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR >>> OTHER >>> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING >>> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER >>> + * DEALINGS IN THE SOFTWARE. >>> + */ >>> + >>> +#include <errno.h> >>> +#include <dlfcn.h> >>> + >>> +#include "egl_dri2.h" >>> + >>> +static int >>> +get_format_bpp(int native) >>> +{ >>> + int bpp; >>> + >>> + switch (native) { >>> + case HAL_PIXEL_FORMAT_RGBA_8888: >>> + case HAL_PIXEL_FORMAT_RGBX_8888: >>> + case HAL_PIXEL_FORMAT_BGRA_8888: >>> + bpp = 4; >>> + break; >>> + case HAL_PIXEL_FORMAT_RGB_888: >>> + bpp = 3; >>> + break; >>> + case HAL_PIXEL_FORMAT_RGB_565: >>> + case HAL_PIXEL_FORMAT_RGBA_5551: >>> + case HAL_PIXEL_FORMAT_RGBA_4444: >>> + bpp = 2; >>> + break; >>> + default: >>> + bpp = 0; >>> + break; >>> + } >>> + >>> + return bpp; >>> +} >>> + >>> +static int >>> +get_native_buffer_name(struct android_native_buffer_t *buf) >>> +{ >>> + struct gralloc_drm_handle_t *handle; >>> + >>> + /* check that the buffer is allocated by drm_gralloc and cast */ >>> + handle = gralloc_drm_handle(buf->handle); >>> + >>> + return (handle) ? handle->name : 0; >>> +} >>> + >>> +static EGLBoolean >>> +droid_dequeue_buffer(struct dri2_egl_surface *dri2_surf) >>> +{ >>> + if (dri2_surf->window->dequeueBuffer(dri2_surf->window, >>> &dri2_surf->buffer)) >>> + return EGL_FALSE; >>> + >>> + dri2_surf->buffer->common.incRef(&dri2_surf->buffer->common); >>> + dri2_surf->window->lockBuffer(dri2_surf->window, dri2_surf->buffer); >>> + >>> + return EGL_TRUE; >>> +} >>> + >>> +static EGLBoolean >>> +droid_enqueue_buffer(struct dri2_egl_surface *dri2_surf) >>> +{ >>> + dri2_surf->window->queueBuffer(dri2_surf->window, dri2_surf->buffer); >>> + >>> + dri2_surf->buffer->common.decRef(&dri2_surf->buffer->common); >>> + dri2_surf->buffer = NULL; >>> + >>> + return EGL_TRUE; >>> +} >>> + >>> +static void >>> +droid_cancel_buffer(struct dri2_egl_surface *dri2_surf) >>> +{ >>> + /* no cancel buffer? */ >>> + droid_enqueue_buffer(dri2_surf); >>> +} >>> + >>> +static __DRIbuffer * >>> +droid_alloc_local_buffer(struct dri2_egl_surface *dri2_surf, >>> + unsigned int att, unsigned int format) >>> +{ >>> + struct dri2_egl_display *dri2_dpy = >>> + dri2_egl_display(dri2_surf->base.Resource.Display); >>> + >>> + if (att >= ARRAY_SIZE(dri2_surf->local_buffers)) >>> + return NULL; >>> + >>> + if (!dri2_surf->local_buffers[att]) { >>> + dri2_surf->local_buffers[att] = >>> + dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen, att, format, >>> + dri2_surf->base.Width, dri2_surf->base.Height); >>> + } >>> + >>> + return dri2_surf->local_buffers[att]; >>> +} >>> + >>> +static void >>> +droid_free_local_buffers(struct dri2_egl_surface *dri2_surf) >>> +{ >>> + struct dri2_egl_display *dri2_dpy = >>> + dri2_egl_display(dri2_surf->base.Resource.Display); >>> + int i; >>> + >>> + for (i = 0; i < ARRAY_SIZE(dri2_surf->local_buffers); i++) { >>> + if (dri2_surf->local_buffers[i]) { >>> + dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen, >>> + dri2_surf->local_buffers[i]); >>> + dri2_surf->local_buffers[i] = NULL; >>> + } >>> + } >>> +} >>> + >>> +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; >>> + >>> + dri2_surf->dri_drawable = >>> + (*dri2_dpy->dri2->createNewDrawable)(dri2_dpy->dri_screen, >>> + dri2_conf->dri_double_config, >>> + 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; >>> +} >>> + >>> +static _EGLSurface * >>> +droid_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp, >>> + _EGLConfig *conf, EGLNativeWindowType window, >>> + const EGLint *attrib_list) >>> +{ >>> + return droid_create_surface(drv, disp, EGL_WINDOW_BIT, conf, >>> + window, attrib_list); >>> +} >>> + >>> +static _EGLSurface * >>> +droid_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *disp, >>> + _EGLConfig *conf, EGLNativePixmapType pixmap, >>> + const EGLint *attrib_list) >>> +{ >>> + return NULL; >>> +} >>> + >>> +static _EGLSurface * >>> +droid_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *disp, >>> + _EGLConfig *conf, const EGLint *attrib_list) >>> +{ >>> + return NULL; >>> +} >>> + >>> +static EGLBoolean >>> +droid_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface >>> *surf) >>> +{ >>> + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); >>> + struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); >>> + >>> + if (!_eglPutSurface(surf)) >>> + return EGL_TRUE; >>> + >>> + droid_free_local_buffers(dri2_surf); >>> + >>> + if (dri2_surf->buffer) >>> + droid_cancel_buffer(dri2_surf); >>> + >>> + dri2_surf->window->common.decRef(&dri2_surf->window->common); >>> + >>> + (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable); >>> + >>> + free(dri2_surf); >>> + >>> + return EGL_TRUE; >>> +} >>> + >>> +static EGLBoolean >>> +droid_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) >>> +{ >>> + struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); >>> + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); >>> + struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); >>> + _EGLContext *ctx; >>> + >>> + if (dri2_drv->glFlush) { >>> + ctx = _eglGetCurrentContext(); >>> + if (ctx && ctx->DrawSurface == &dri2_surf->base) >>> + dri2_drv->glFlush(); >>> + } >>> + >>> + (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable); >>> + >>> + if (dri2_surf->buffer) >>> + droid_enqueue_buffer(dri2_surf); >>> + >>> + (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable); >>> + >>> + return EGL_TRUE; >>> +} >>> + >>> +static void >>> +droid_init_driver_functions(_EGLDriver *drv) >>> +{ >>> + drv->API.CreateWindowSurface = droid_create_window_surface; >>> + drv->API.CreatePixmapSurface = droid_create_pixmap_surface; >>> + drv->API.CreatePbufferSurface = droid_create_pbuffer_surface; >>> + drv->API.DestroySurface = droid_destroy_surface; >>> + drv->API.SwapBuffers = droid_swap_buffers; >>> +} >>> + >>> +static void >>> +droid_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate) >>> +{ >>> +} >>> + >>> +static __DRIbuffer * >>> +droid_get_buffers_with_format(__DRIdrawable * driDrawable, >>> + int *width, int *height, >>> + unsigned int *attachments, int count, >>> + int *out_count, void *loaderPrivate) >>> +{ >>> + struct dri2_egl_surface *dri2_surf = loaderPrivate; >>> + struct dri2_egl_display *dri2_dpy = >>> + dri2_egl_display(dri2_surf->base.Resource.Display); >>> + int i; >>> + >>> + if (!dri2_surf->buffer) { >>> + if (!droid_dequeue_buffer(dri2_surf)) >>> + return NULL; >>> + } >>> + >>> + /* free outdated buffers and update the surface size */ >>> + if (dri2_surf->base.Width != dri2_surf->buffer->width || >>> + dri2_surf->base.Height != dri2_surf->buffer->height) { >>> + droid_free_local_buffers(dri2_surf); >>> + dri2_surf->base.Width = dri2_surf->buffer->width; >>> + dri2_surf->base.Height = dri2_surf->buffer->height; >>> + } >>> + >>> + dri2_surf->buffer_count = 0; >>> + for (i = 0; i < count * 2; i += 2) { >>> + __DRIbuffer *buf, *local; >>> + >>> + assert(dri2_surf->buffer_count < ARRAY_SIZE(dri2_surf->buffers)); >>> + buf = &dri2_surf->buffers[dri2_surf->buffer_count]; >>> + >>> + switch (attachments[i]) { >>> + case __DRI_BUFFER_BACK_LEFT: >>> + buf->attachment = attachments[i]; >>> + buf->name = get_native_buffer_name(dri2_surf->buffer); >>> + buf->cpp = get_format_bpp(dri2_surf->buffer->format); >>> + buf->pitch = dri2_surf->buffer->stride * buf->cpp; >>> + buf->flags = 0; >>> + >>> + dri2_surf->buffer_count++; >>> + break; >>> + case __DRI_BUFFER_DEPTH: >>> + case __DRI_BUFFER_STENCIL: >>> + case __DRI_BUFFER_ACCUM: >>> + case __DRI_BUFFER_DEPTH_STENCIL: >>> + case __DRI_BUFFER_HIZ: >>> + local = droid_alloc_local_buffer(dri2_surf, >>> + attachments[i], attachments[i + 1]); >>> + >>> + if (local) { >>> + *buf = *local; >>> + dri2_surf->buffer_count++; >>> + } >>> + break; >>> + case __DRI_BUFFER_FRONT_LEFT: >>> + case __DRI_BUFFER_FRONT_RIGHT: >>> + case __DRI_BUFFER_FAKE_FRONT_LEFT: >>> + case __DRI_BUFFER_FAKE_FRONT_RIGHT: >>> + case __DRI_BUFFER_BACK_RIGHT: >>> + default: >>> + /* no front or right buffers */ >>> + break; >>> + } >>> + } >>> + >>> + if (width) >>> + *width = dri2_surf->base.Width; >>> + if (height) >>> + *height = dri2_surf->base.Height; >>> + >>> + *out_count = dri2_surf->buffer_count;; >>> + >>> + return dri2_surf->buffers; >>> +} >>> + >>> +static EGLBoolean >>> +droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy) >>> +{ >>> + struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy); >>> + const struct { >>> + int format; >>> + int size; >>> + unsigned int rgba_masks[4]; >>> + } visuals[] = { >>> + { HAL_PIXEL_FORMAT_RGBA_8888, 32, { 0xff, 0xff00, 0xff0000, >>> 0xff000000 } }, >>> + { HAL_PIXEL_FORMAT_RGBX_8888, 32, { 0xff, 0xff00, 0xff0000, 0x0 } }, >>> + { HAL_PIXEL_FORMAT_RGB_888, 24, { 0xff, 0xff00, 0xff0000, 0x0 } }, >>> + { HAL_PIXEL_FORMAT_RGB_565, 16, { 0xf800, 0x7e0, 0x1f, 0x0 } }, >>> + { HAL_PIXEL_FORMAT_BGRA_8888, 32, { 0xff0000, 0xff00, 0xff, >>> 0xff000000 } }, >>> + { 0, 0, { 0, 0, 0, 0 } } >>> + }; >>> + int count, i, j; >>> + >>> + count = 0; >>> + for (i = 0; visuals[i].format; i++) { >>> + int format_count = 0; >>> + >>> + for (j = 0; dri2_dpy->driver_configs[j]; j++) { >>> + struct dri2_egl_config *dri2_conf; >>> + >>> + dri2_conf = dri2_add_config(dpy, dri2_dpy->driver_configs[j], >>> + count + 1, visuals[i].size, EGL_WINDOW_BIT, NULL, >>> + visuals[i].rgba_masks); >>> + if (dri2_conf) { >>> + dri2_conf->base.NativeVisualID = visuals[i].format; >>> + dri2_conf->base.NativeVisualType = visuals[i].format; >>> + count++; >>> + format_count++; >>> + } >>> + } >>> + >>> + if (!format_count) { >>> + _eglLog(_EGL_DEBUG, "No DRI config supports native format 0x%x", >>> + visuals[i].format); >>> + } >>> + } >>> + >>> + return (count != 0); >>> +} >>> + >>> +#include <xf86drm.h> >>> +/* for i915 */ >>> +#include <i915_drm.h> >>> +/* for radeon */ >>> +#include <radeon_drm.h> >>> +static EGLBoolean >>> +droid_get_pci_id(int fd, int *vendor_id, int *chip_id) >>> +{ >>> + drmVersionPtr version; >>> + >>> + *chip_id = -1; >>> + >>> + version = drmGetVersion(fd); >>> + if (!version) { >>> + _eglLog(_EGL_WARNING, "invalid drm fd"); >>> + return EGL_FALSE; >>> + } >>> + if (!version->name) { >>> + _eglLog(_EGL_WARNING, "unable to determine the driver name"); >>> + drmFreeVersion(version); >>> + return EGL_FALSE; >>> + } >>> + >>> + if (strcmp(version->name, "i915") == 0) { >>> + struct drm_i915_getparam gp; >>> + int ret; >>> + >>> + *vendor_id = 0x8086; >>> + >>> + memset(&gp, 0, sizeof(gp)); >>> + gp.param = I915_PARAM_CHIPSET_ID; >>> + gp.value = chip_id; >>> + ret = drmCommandWriteRead(fd, DRM_I915_GETPARAM, &gp, sizeof(gp)); >>> + if (ret) { >>> + _eglLog(_EGL_WARNING, "failed to get param for i915"); >>> + *chip_id = -1; >>> + } >>> + } >>> + else if (strcmp(version->name, "radeon") == 0) { >>> + struct drm_radeon_info info; >>> + int ret; >>> + >>> + *vendor_id = 0x1002; >>> + >>> + memset(&info, 0, sizeof(info)); >>> + info.request = RADEON_INFO_DEVICE_ID; >>> + info.value = (long) chip_id; >> >> As in the gallium commit, rather cast to unsigned long here :) > Will do. Missed this one.. >>> + ret = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)); >>> + if (ret) { >>> + _eglLog(_EGL_WARNING, "failed to get info for radeon"); >>> + *chip_id = -1; >>> + } >>> + } >>> + >>> + drmFreeVersion(version); >>> + >>> + return (*chip_id >= 0); >>> +} >>> + >>> +#define DRIVER_MAP_DRI2_ONLY >>> +#include "pci_ids/pci_id_driver_map.h" >>> +static const char * >>> +droid_get_driver_name(int fd) >>> +{ >>> + int vendor_id = -1, chip_id = -1; >>> + int idx, i; >>> + char *name; >>> + >>> + if (!droid_get_pci_id(fd, &vendor_id, &chip_id)) >>> + return NULL; >>> + >>> + for (idx = 0; driver_map[idx].driver; idx++) { >>> + if (vendor_id != driver_map[idx].vendor_id) >>> + continue; >>> + >>> + if (driver_map[idx].num_chips_ids == -1) >>> + break; >>> + >>> + for (i = 0; i < driver_map[idx].num_chips_ids; i++) { >>> + if (driver_map[idx].chip_ids[i] == chip_id) >>> + break; >>> + } >>> + if (i < driver_map[idx].num_chips_ids) >>> + break; >>> + } >>> + >>> + _eglLog(_EGL_INFO, "pci id for fd %d: %04x:%04x, driver %s", >>> + fd, vendor_id, chip_id, driver_map[idx].driver); >>> + >>> + return driver_map[idx].driver; >>> +} >>> + >>> +static int >>> +droid_open_device(void) >>> +{ >>> + const hw_module_t *mod; >>> + int fd = -1, err; >>> + >>> + err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mod); >>> + if (!err) { >>> + const gralloc_module_t *gr = (gralloc_module_t *) mod; >>> + >>> + err = -EINVAL; >>> + if (gr->perform) >>> + err = gr->perform(gr, GRALLOC_MODULE_PERFORM_GET_DRM_FD, &fd); >>> + } >>> + if (err || fd < 0) { >>> + _eglLog(_EGL_WARNING, "fail to get drm fd"); >>> + fd = -1; >>> + } >>> + >>> + return (fd >= 0) ? dup(fd) : -1; >>> +} >>> + >>> +EGLBoolean >>> +dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *dpy) >>> +{ >>> + struct dri2_egl_display *dri2_dpy; >>> + const char *err; >>> + >>> + dri2_dpy = calloc(1, sizeof(*dri2_dpy)); >>> + if (!dri2_dpy) >>> + return _eglError(EGL_BAD_ALLOC, "eglInitialize"); >>> + >>> + dpy->DriverData = (void *) dri2_dpy; >>> + >>> + dri2_dpy->fd = droid_open_device(); >>> + if (dri2_dpy->fd < 0) { >>> + err = "DRI2: failed to open device"; >>> + goto cleanup_display; >>> + } >>> + >>> + dri2_dpy->driver_name = (char *) droid_get_driver_name(dri2_dpy->fd); >>> + if (dri2_dpy->driver_name == NULL) { >>> + err = "DRI2: failed to get driver name"; >>> + goto cleanup_device; >>> + } >>> + >>> + if (!dri2_load_driver(dpy)) { >>> + err = "DRI2: failed to load driver"; >>> + goto cleanup_device; >>> + } >>> + >>> + dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER; >>> + dri2_dpy->dri2_loader_extension.base.version = 3; >>> + dri2_dpy->dri2_loader_extension.getBuffers = NULL; >>> + dri2_dpy->dri2_loader_extension.flushFrontBuffer = >>> droid_flush_front_buffer; >>> + dri2_dpy->dri2_loader_extension.getBuffersWithFormat = >>> + droid_get_buffers_with_format; >>> + >>> + dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base; >>> + dri2_dpy->extensions[1] = &image_lookup_extension.base; >>> + dri2_dpy->extensions[2] = &use_invalidate.base; >>> + dri2_dpy->extensions[3] = NULL; >>> + >>> + if (!dri2_create_screen(dpy)) { >>> + err = "DRI2: failed to create screen"; >>> + goto cleanup_driver; >>> + } >>> + >>> + if (!droid_add_configs_for_visuals(drv, dpy)) { >>> + err = "DRI2: failed to add configs"; >>> + goto cleanup_screen; >>> + } >>> + >>> + dpy->Extensions.ANDROID_image_native_buffer = EGL_TRUE; >>> + dpy->Extensions.KHR_image_base = EGL_TRUE; >>> + >>> + /* we're supporting EGL 1.4 */ >>> + dpy->VersionMajor = 1; >>> + dpy->VersionMinor = 4; >>> + >>> + droid_init_driver_functions(drv); >>> + >>> + return EGL_TRUE; >>> + >>> +cleanup_screen: >>> + dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen); >>> +cleanup_driver: >>> + dlclose(dri2_dpy->driver); >>> +cleanup_device: >>> + close(dri2_dpy->fd); >>> +cleanup_display: >>> + free(dri2_dpy); >>> + >>> + return _eglError(EGL_NOT_INITIALIZED, err); >>> +} >>> -- >>> 1.7.5.4 >>> >>> _______________________________________________ >>> mesa-dev mailing list >>> mesa-dev@lists.freedesktop.org >>> http://lists.freedesktop.org/mailman/listinfo/mesa-dev >>> >> > > > > -- > o...@lunarg.com > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev