diff options
| author | Chia-I Wu <olvaffe@gmail.com> | 2009-09-18 17:13:20 +0800 | 
|---|---|---|
| committer | Chia-I Wu <olvaffe@gmail.com> | 2009-09-18 18:36:14 +0800 | 
| commit | 6059e6a8f25e15e934a268d1f022044736f8ba33 (patch) | |
| tree | 2eb0a37925672d3ec8932efeafa75aee21011f09 | |
| parent | 3c718c0e95583c3c080bb0e7020b39066a265fa1 (diff) | |
egl_android: Add untested support for EGLImage.
| -rw-r--r-- | src/egl/drivers/android/droid.h | 11 | ||||
| -rw-r--r-- | src/egl/drivers/android/droid_intel.c | 73 | ||||
| -rw-r--r-- | src/egl/drivers/android/droid_loader.c | 77 | ||||
| -rw-r--r-- | 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 <assert.h>  #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; | 
