From 6059e6a8f25e15e934a268d1f022044736f8ba33 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 18 Sep 2009 17:13:20 +0800 Subject: egl_android: Add untested support for EGLImage. --- src/egl/drivers/android/droid.h | 11 ++++ src/egl/drivers/android/droid_intel.c | 73 +++++++++++++++++++++-- src/egl/drivers/android/droid_loader.c | 77 ++++++++++++++++++++++++ src/egl/drivers/android/egl_android.c | 103 ++++++++++++++++++++++++++++++++- 4 files changed, 257 insertions(+), 7 deletions(-) diff --git a/src/egl/drivers/android/droid.h b/src/egl/drivers/android/droid.h index bed5e8cd75..1793f6a78c 100644 --- a/src/egl/drivers/android/droid.h +++ b/src/egl/drivers/android/droid.h @@ -40,6 +40,7 @@ struct droid_loader; struct droid_context; struct droid_drawable; +struct droid_image; struct droid_surface; struct droid_backend { @@ -61,6 +62,9 @@ struct droid_backend { struct droid_surface *(*create_window_surface)(struct droid_backend *backend, _EGLSurface *surf, NativeWindowType win); + struct droid_surface *(*create_image_surface)(struct droid_backend *backend, + NativePixmapType pix, + int *depth); void (*destroy_surface)(struct droid_backend *backend, struct droid_surface *surf); void (*swap_native_buffers)(struct droid_backend *backend, struct droid_surface *surf); @@ -75,6 +79,9 @@ struct droid_screen { const __DRIconfig **dri_configs; int num_dri_configs; + +#define DROID_MAX_IMAGE_DEPTH 32 + const __DRIconfig *image_configs[DROID_MAX_IMAGE_DEPTH + 1]; }; struct droid_backend * @@ -107,6 +114,10 @@ droid_screen_create_drawable(struct droid_screen *screen, const __DRIconfig *conf, struct droid_surface *surf); +void * +droid_screen_get_drawable_data(struct droid_screen *screen, + struct droid_drawable *drawable); + void droid_screen_destroy_drawable(struct droid_screen *screen, struct droid_drawable *drawable); diff --git a/src/egl/drivers/android/droid_intel.c b/src/egl/drivers/android/droid_intel.c index 2f1b26c53f..d9ff0d59d6 100644 --- a/src/egl/drivers/android/droid_intel.c +++ b/src/egl/drivers/android/droid_intel.c @@ -46,6 +46,7 @@ enum { INTEL_SURFACE_TYPE_WINDOW, + INTEL_SURFACE_TYPE_IMAGE, }; struct droid_backend_intel { @@ -58,6 +59,7 @@ struct droid_surface_intel { int type; union { NativeWindowType win; + NativePixmapType pix; } native; __DRIbuffer native_buffer; unsigned int native_width, native_height; @@ -219,11 +221,20 @@ intel_get_surface_buffers(struct droid_backend *backend, } else { buffers[num].attachment = att; - handles[num] = create_buffer(intel->fd, - isurf->native_width, - isurf->native_height, - cpp, - &buffers[num]); + + if (isurf->type == INTEL_SURFACE_TYPE_IMAGE && + att == __DRI_BUFFER_FRONT_LEFT) { + buffers[num] = isurf->native_buffer; + buffers[num].attachment = att; + handles[num] = 0; + } else { + buffers[num].attachment = att; + handles[num] = create_buffer(intel->fd, + isurf->native_width, + isurf->native_height, + cpp, + &buffers[num]); + } } num++; } @@ -258,6 +269,13 @@ update_native_buffer(struct droid_surface *surf) width = isurf->native.win->width; height = isurf->native.win->height; break; + case INTEL_SURFACE_TYPE_IMAGE: + name = isurf->native.pix->reserved; + cpp = ui_bytes_per_pixel(isurf->native.pix->format); + pitch = isurf->native.pix->stride * cpp; + width = isurf->native.pix->width; + height = isurf->native.pix->height; + break; default: name = cpp = pitch = width = height = 0; break; @@ -316,6 +334,50 @@ intel_create_window_surface(struct droid_backend *backend, return (struct droid_surface *) isurf; } +static struct droid_surface * +intel_create_image_surface(struct droid_backend *backend, + NativePixmapType pix, int *depth) +{ + struct droid_surface_intel *isurf; + int cpp; + + if (!pix) { + LOGE("invalid native pixmap"); + _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCreateImage"); + return NULL; + } + + /* TODO lift this limitation */ + if (!pix->reserved) { + LOGE("TODO support for non-gem based pixmap"); + _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCreateImage"); + return NULL; + } + + cpp = ui_bytes_per_pixel(pix->format); + if (cpp * 8 > DROID_MAX_IMAGE_DEPTH) { + LOGE("pixmap of depth %d is not supported", cpp * 8); + _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCreateImage"); + return NULL; + } + + isurf = calloc(1, sizeof(*isurf)); + if (!isurf) { + _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface"); + return NULL; + } + + isurf->type = INTEL_SURFACE_TYPE_IMAGE; + isurf->native.pix = pix; + + update_native_buffer((struct droid_surface *) isurf); + + if (depth) + *depth = cpp * 8; + + return (struct droid_surface *) isurf; +} + static void intel_destroy_surface(struct droid_backend *backend, struct droid_surface *surf) { @@ -400,6 +462,7 @@ droid_backend_create_intel(const char *dev) intel->base.get_surface_buffers = intel_get_surface_buffers; intel->base.create_window_surface = intel_create_window_surface; + intel->base.create_image_surface = intel_create_image_surface; intel->base.destroy_surface = intel_destroy_surface; intel->base.swap_native_buffers = intel_swap_native_buffers; diff --git a/src/egl/drivers/android/droid_loader.c b/src/egl/drivers/android/droid_loader.c index 1d02b49322..67e8e9f2b1 100644 --- a/src/egl/drivers/android/droid_loader.c +++ b/src/egl/drivers/android/droid_loader.c @@ -33,6 +33,7 @@ #include #include "droid.h" +#include "EGL/internal/eglimage_dri.h" #ifndef DROID_DRIVER_PATH #define DROID_DRIVER_PATH "/system/lib" @@ -57,6 +58,8 @@ struct droid_drawable { struct droid_surface *surface; __DRIdrawable *dri_drawable; + const __DRIconfig *dri_config; + __DRIEGLImage *dri_image; }; static __DRIbuffer * @@ -206,6 +209,48 @@ droid_backend_destroy(struct droid_backend *backend) backend->destroy(backend); } +static void +screen_find_image_configs(struct droid_screen *screen) +{ + struct droid_loader *loader = screen->loader; + int depth, i; + + for (depth = 0; depth < DROID_MAX_IMAGE_DEPTH + 1; depth++) { + for (i = 0; i < screen->num_dri_configs; i++) { + const __DRIconfig *conf = screen->dri_configs[i]; + _EGLConfig egl_conf; + EGLint rgba, val; + + droid_screen_convert_config(screen, conf, &egl_conf); + + val = GET_CONFIG_ATTRIB(&egl_conf, EGL_CONFIG_CAVEAT); + if (val == EGL_SLOW_CONFIG) + continue; + + rgba = GET_CONFIG_ATTRIB(&egl_conf, EGL_RED_SIZE); + rgba += GET_CONFIG_ATTRIB(&egl_conf, EGL_GREEN_SIZE); + rgba += GET_CONFIG_ATTRIB(&egl_conf, EGL_BLUE_SIZE); + rgba += GET_CONFIG_ATTRIB(&egl_conf, EGL_ALPHA_SIZE); + if (depth != rgba) + continue; + + if (depth == 32) { + val = GET_CONFIG_ATTRIB(&egl_conf, EGL_BIND_TO_TEXTURE_RGBA); + if (val) { + screen->image_configs[depth] = conf; + break; + } + } + + val = GET_CONFIG_ATTRIB(&egl_conf, EGL_BIND_TO_TEXTURE_RGB); + if (val) { + screen->image_configs[depth] = conf; + break; + } + } + } +} + struct droid_screen * droid_screen_create(struct droid_backend *backend) { @@ -268,6 +313,8 @@ droid_screen_create(struct droid_backend *backend) ; screen->num_dri_configs = i; + screen_find_image_configs(screen); + return screen; fail: @@ -400,6 +447,7 @@ droid_screen_create_drawable(struct droid_screen *screen, /* needed in GetBuffers */ drawable->loader = loader; drawable->surface = surf; + drawable->dri_config = conf; drawable->dri_drawable = loader->dri2->createNewDrawable(screen->dri_screen, @@ -413,11 +461,40 @@ droid_screen_create_drawable(struct droid_screen *screen, return drawable; } +void * +droid_screen_get_drawable_data(struct droid_screen *screen, + struct droid_drawable *drawable) +{ + struct droid_loader *loader = screen->loader; + __DRIEGLImage *img = drawable->dri_image; + + if (!img) { + unsigned int val; + + img = calloc(1, sizeof(__DRIEGLImage)); + if (!img) + return NULL; + + img->magic = __DRI_EGL_IMAGE_MAGIC; + img->drawable = drawable->dri_drawable; + img->level = 0; + if (loader->core->getConfigAttrib(drawable->dri_config, + EGL_BIND_TO_TEXTURE_RGBA, &val)) + img->texture_format_rgba = val; + + drawable->dri_image = img; + } + + return (void *) img; +} + void droid_screen_destroy_drawable(struct droid_screen *screen, struct droid_drawable *drawable) { struct droid_loader *loader = screen->loader; + if (drawable->dri_image) + free(drawable->dri_image); loader->core->destroyDrawable(drawable->dri_drawable); free(drawable); } diff --git a/src/egl/drivers/android/egl_android.c b/src/egl/drivers/android/egl_android.c index 10c0aea3ab..e9e0114683 100644 --- a/src/egl/drivers/android/egl_android.c +++ b/src/egl/drivers/android/egl_android.c @@ -32,8 +32,6 @@ #include "eglsurface.h" #include "eglimage.h" -#include "EGL/internal/eglimage_dri.h" - #include "droid.h" #ifndef DROID_DEVICE_PATH @@ -73,6 +71,12 @@ struct droid_egl_surface { struct droid_surface *surface; }; +struct droid_egl_image { + _EGLImage base; + struct droid_drawable *drawable; + struct droid_surface *surface; +}; + struct droid_egl_config { _EGLConfig base; const __DRIconfig *config; @@ -102,6 +106,12 @@ lookup_surface(_EGLSurface *surface) return (struct droid_egl_surface *) surface; } +static INLINE struct droid_egl_image * +lookup_image(_EGLImage *image) +{ + return (struct droid_egl_image *) image; +} + static INLINE struct droid_egl_config * lookup_config(_EGLConfig *conf) { @@ -184,6 +194,14 @@ droid_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy, droid_create_configs(dpy, droid_dpy, droid_dpy->screen->dri_configs, droid_dpy->screen->num_dri_configs); +#if EGL_KHR_image_base + if (droid_dpy->backend->create_image_surface) { + dpy->Extensions.KHR_image = EGL_TRUE; + dpy->Extensions.KHR_image_base = EGL_TRUE; + dpy->Extensions.KHR_image_pixmap = EGL_TRUE; + } +#endif + droid_drv->default_display = droid_dpy; } @@ -380,6 +398,83 @@ droid_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) return EGL_TRUE; } +#if EGL_KHR_image_base + +static _EGLImage * +droid_eglCreateImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, + EGLenum target, EGLClientBuffer buffer, const EGLint *attr_list) +{ + struct droid_egl_display *droid_dpy = lookup_display(dpy); + struct droid_egl_image *droid_img; + const __DRIconfig *dri_conf; + int depth; + + if (target != EGL_NATIVE_PIXMAP_KHR || ctx) { + _eglError(EGL_BAD_PARAMETER, "eglCreateImageKHR"); + return NULL; + } + + droid_img = calloc(1, sizeof(*droid_img)); + if (!droid_img) { + _eglError(EGL_BAD_ALLOC, "eglCreateImageKHR"); + return NULL; + } + + if (!_eglInitImage(drv, &droid_img->base, attr_list)) { + free(droid_img); + return NULL; + } + + droid_img->surface = + droid_dpy->backend->create_image_surface(droid_dpy->backend, + (NativePixmapType) buffer, + &depth); + if (!droid_img->surface) { + free(droid_img); + return NULL; + } + + dri_conf = droid_dpy->screen->image_configs[depth]; + if (!dri_conf) { + droid_dpy->backend->destroy_surface(droid_dpy->backend, + droid_img->surface); + free(droid_img); + return NULL; + } + + droid_img->drawable = + droid_screen_create_drawable(droid_dpy->screen, dri_conf, + droid_img->surface); + + if (!droid_img->drawable) { + droid_dpy->backend->destroy_surface(droid_dpy->backend, + droid_img->surface); + free(droid_img); + return NULL; + } + + droid_img->base.ClientData = + droid_screen_get_drawable_data(droid_dpy->screen, droid_img->drawable); + + return &droid_img->base; +} + + +static EGLBoolean +droid_eglDestroyImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img) +{ + struct droid_egl_display *droid_dpy = lookup_display(dpy); + struct droid_egl_image *droid_img = lookup_image(img); + + droid_screen_destroy_drawable(droid_dpy->screen, droid_img->drawable); + droid_dpy->backend->destroy_surface(droid_dpy->backend, droid_img->surface); + free(droid_img); + + return EGL_TRUE; +} + +#endif /* EGL_KHR_image_base */ + static EGLBoolean droid_eglWaitClient(_EGLDriver *drv, _EGLDisplay *dpy) { @@ -446,6 +541,10 @@ _eglMain(const char *args) droid_drv->base.API.CreateWindowSurface = droid_eglCreateWindowSurface; droid_drv->base.API.DestroySurface = droid_eglDestroySurface; droid_drv->base.API.SwapBuffers = droid_eglSwapBuffers; +#if EGL_KHR_image_base + droid_drv->base.API.CreateImageKHR = droid_eglCreateImageKHR; + droid_drv->base.API.DestroyImageKHR = droid_eglDestroyImageKHR; +#endif /* EGL_KHR_image_base */ droid_drv->base.API.WaitClient = droid_eglWaitClient; droid_drv->base.API.WaitNative = droid_eglWaitNative; -- cgit v1.2.3