[Mesa-dev] [PATCH 4/4] egl: Add EGL_MESA_create_image extension

Brian Paul brianp at vmware.com
Fri May 28 08:05:36 PDT 2010


Minor code comments below.


Kristian Høgsberg wrote:
> ---
>  include/EGL/eglext.h                       |   18 +++++
>  include/GL/internal/dri_interface.h        |   13 +++
>  src/egl/drivers/dri2/egl_dri2.c            |  110 ++++++++++++++++++++++++++++
>  src/egl/main/eglapi.c                      |   21 +++++-
>  src/egl/main/eglapi.h                      |    9 ++
>  src/mesa/drivers/dri/intel/intel_regions.c |   19 +++++
>  src/mesa/drivers/dri/intel/intel_regions.h |    5 +
>  src/mesa/drivers/dri/intel/intel_screen.c  |   75 +++++++++++++++++++
>  8 files changed, 269 insertions(+), 1 deletions(-)
> 
> diff --git a/include/EGL/eglext.h b/include/EGL/eglext.h
> index 664fe55..db6b8e9 100644
> --- a/include/EGL/eglext.h
> +++ b/include/EGL/eglext.h
> @@ -120,6 +120,24 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGL
>  #define EGL_GL_RENDERBUFFER_KHR                        0x30B9  /* eglCreateImageKHR target */
>  #endif
> 
> +/* FIXME: Unauthorized enum valus ahead! */
> +#ifndef EGL_MESA_create_image
> +#define EGL_MESA_create_image 1
> +#define EGL_NEW_IMAGE_MESA                     0x8080  /* eglCreateImageKHR target */
> +#define EGL_IMAGE_FORMAT_MESA                  0x8083  /* eglCreateImageKHR attribute */
> +#define EGL_IMAGE_USE_MESA                     0x8086  /* eglCreateImageKHR attribute */
> +
> +#define EGL_IMAGE_USE_SCANOUT_MESA             0x0002  /* EGL_IMAGE_USE_MESA value */
> +
> +#define EGL_IMAGE_HANDLE_MESA                  0x8084  /* eglQueryImageKHR attribute */
> +#define EGL_IMAGE_STRIDE_MESA                  0x8085  /* eglQueryImageKHR attribute */
> +
> +#ifdef EGL_EGLEXT_PROTOTYPES
> +EGLAPI EGLBoolean EGLAPIENTRY eglQueryImageMESA (EGLDisplay dpy, EGLImageKHR image, EGLint attribute, EGLint *value);
> +#endif
> +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYIMAGEMESA) (EGLDisplay dpy, EGLImageKHR image, EGLint attribute, EGLint *value);
> +#endif
> +
>  #ifndef EGL_KHR_reusable_sync
>  #define EGL_KHR_reusable_sync 1
> 
> diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
> index e4c2b3a..57d6511 100644
> --- a/include/GL/internal/dri_interface.h
> +++ b/include/GL/internal/dri_interface.h
> @@ -807,6 +807,9 @@ struct __DRIdri2ExtensionRec {
>  #define __DRI_IMAGE_FORMAT_XRGB8888     0x1002
>  #define __DRI_IMAGE_FORMAT_ARGB8888     0x1003
> 
> +#define __DRI_IMAGE_USE_SHARE          0x0001
> +#define __DRI_IMAGE_USE_SCANOUT                0x0002
> +
>  typedef struct __DRIimageRec          __DRIimage;
>  typedef struct __DRIimageExtensionRec __DRIimageExtension;
>  struct __DRIimageExtensionRec {
> @@ -822,8 +825,18 @@ struct __DRIimageExtensionRec {
>                                                void *loaderPrivate);
> 
>      void (*destroyImage)(__DRIimage *image);
> +
> +    /* Since version 2 */
> +    __DRIimage *(*createImage)(__DRIcontext *context,
> +                              int width, int height, int format,
> +                              unsigned int use,
> +                              void *loaderPrivate);
> +
> +    GLboolean (*queryImage)(__DRIimage *image,
> +                           int *format, uint32_t *handle, int *pitch);
>  };
> 
> +
>  /**
>   * This extension must be implemented by the loader and passed to the
>   * driver at screen creation time.  The EGLImage entry points in the
> diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
> index 7779cd8..9c81077 100644
> --- a/src/egl/drivers/dri2/egl_dri2.c
> +++ b/src/egl/drivers/dri2/egl_dri2.c
> @@ -1525,6 +1525,78 @@ dri2_create_image_khr_renderbuffer(_EGLDisplay *disp, _EGLContext *ctx,
>  }
> 
>  static _EGLImage *
> +dri2_create_image_khr_mesa(_EGLDisplay *disp, _EGLContext *ctx,
> +                          EGLClientBuffer buffer,
> +                          const EGLint *attr_list)
> +{
> +   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
> +   struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
> +   struct dri2_egl_image *dri2_img;
> +   int width, height, format, i;
> +   unsigned int use;
> +
> +   dri2_img = malloc(sizeof *dri2_img);
> +   if (!dri2_img) {
> +      _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr");
> +      return EGL_NO_IMAGE_KHR;
> +   }
> +
> +   if (!_eglInitImage(&dri2_img->base, disp, attr_list)) {
> +      free(dri2_img);
> +      return EGL_NO_IMAGE_KHR;
> +   }
> +
> +   if (!attr_list) {
> +      free(dri2_img);
> +      _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
> +      return EGL_NO_IMAGE_KHR;
> +   }
> +
> +   for (i = 0; attr_list[i] != EGL_NONE; i += 2) {
> +      EGLint attr = attr_list[i];
> +      EGLint val = attr_list[i + 1];
> +
> +      switch (attr) {
> +      case EGL_WIDTH:
> +        width = val;
> +         break;
> +      case EGL_HEIGHT:
> +        height = val;
> +         break;
> +      case EGL_IMAGE_FORMAT_MESA:
> +        format = val;
> +         break;
> +      case EGL_IMAGE_USE_MESA:
> +        use = val;
> +         break;

Shouldn't there be a default case here to catch invalid attributes and 
generate an error?



> +      }
> +   }
> +
> +   switch (format) {
> +   case EGL_FORMAT_RGB_565_KHR:
> +      format = __DRI_IMAGE_FORMAT_RGB565;
> +      break;
> +   case EGL_FORMAT_RGBA_8888_KHR:
> +      format = __DRI_IMAGE_FORMAT_XRGB8888;
> +      break;
> +   default:
> +      _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
> +      free(dri2_img);
> +      return EGL_NO_IMAGE_KHR;
> +   }
> +
> +   dri2_img->dri_image =
> +      dri2_dpy->image->createImage(dri2_ctx->dri_context,
> +                                  width, height, format, use, dri2_img);
> +   if (dri2_img->dri_image == NULL) {
> +      free(dri2_img);
> +      return EGL_NO_IMAGE_KHR;
> +   }
> +
> +   return &dri2_img->base;
> +}
> +
> +static _EGLImage *
>  dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
>                       _EGLContext *ctx, EGLenum target,
>                       EGLClientBuffer buffer, const EGLint *attr_list)
> @@ -1534,6 +1606,8 @@ dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
>        return dri2_create_image_khr_pixmap(disp, ctx, buffer, attr_list);
>     case EGL_GL_RENDERBUFFER_KHR:
>        return dri2_create_image_khr_renderbuffer(disp, ctx, buffer, attr_list);
> +   case EGL_NEW_IMAGE_MESA:
> +      return dri2_create_image_khr_mesa(disp, ctx, buffer, attr_list);
>     default:
>        _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
>        return EGL_NO_IMAGE_KHR;
> @@ -1552,6 +1626,41 @@ dri2_destroy_image_khr(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *image)
>     return EGL_TRUE;
>  }
> 
> +static EGLBoolean
> +dri2_query_image_mesa(_EGLDriver *drv, _EGLDisplay *disp,
> +                     _EGLImage *image, EGLint attribute, EGLint *value)
> +{
> +   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
> +   struct dri2_egl_image *dri2_img = dri2_egl_image(image);
> +   int format, pitch;
> +   uint32_t handle;
> +
> +   dri2_dpy->image->queryImage(dri2_img->dri_image,
> +                              &format, &handle, &pitch);
> +   switch (format) {
> +   case __DRI_IMAGE_FORMAT_RGB565:
> +      format = EGL_FORMAT_RGB_565_KHR;
> +      break;
> +   case __DRI_IMAGE_FORMAT_XRGB8888:
> +      format = EGL_FORMAT_RGBA_8888_KHR;
> +      break;

Default case?


> +   }
> +
> +   switch (attribute) {
> +   case EGL_IMAGE_FORMAT_MESA:
> +      *value = format;
> +      return EGL_TRUE;
> +   case EGL_IMAGE_HANDLE_MESA:
> +      *value = handle;
> +      return EGL_TRUE;
> +   case EGL_IMAGE_STRIDE_MESA:
> +      *value = pitch;
> +      return EGL_TRUE;

Default case?

> +   }
> +
> +   return EGL_FALSE;
> +}
> +
>  /**
>   * This is the main entrypoint into the driver, called by libEGL.
>   * Create a new _EGLDriver object and init its dispatch table.
> @@ -1585,6 +1694,7 @@ _eglMain(const char *args)
>     dri2_drv->base.API.CreateImageKHR = dri2_create_image_khr;
>     dri2_drv->base.API.DestroyImageKHR = dri2_destroy_image_khr;
>     dri2_drv->base.API.SwapBuffersRegionNOK = dri2_swap_buffers_region;
> +   dri2_drv->base.API.QueryImageMESA = dri2_query_image_mesa;
> 
>     dri2_drv->base.Name = "DRI2";
>     dri2_drv->base.Unload = dri2_unload;
> diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
> index d158714..86a3122 100644
> --- a/src/egl/main/eglapi.c
> +++ b/src/egl/main/eglapi.c
> @@ -1258,7 +1258,6 @@ eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
>     RETURN_EGL_EVAL(disp, ret);
>  }
> 
> -
>  #endif /* EGL_KHR_image_base */
> 
> 
> @@ -1289,3 +1288,23 @@ eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
>  }
> 
>  #endif /* EGL_NOK_swap_region */
> +
> +#ifdef EGL_MESA_create_image
> +
> +EGLBoolean
> +eglQueryImageMESA(EGLDisplay dpy, EGLImageKHR image,
> +                  EGLint attribute, EGLint *value)
> +{
> +   _EGLDisplay *disp = _eglLockDisplay(dpy);
> +   _EGLImage *img = _eglLookupImage(image, disp);
> +   _EGLDriver *drv;
> +   EGLBoolean ret;
> +
> +   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
> +
> +   ret = drv->API.QueryImageMESA(drv, disp, img, attribute, value);
> +
> +   RETURN_EGL_EVAL(disp, ret);
> +}
> +
> +#endif /* EGL_MESA_create_image */
> diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h
> index d8c8b49..8f75fc6 100644
> --- a/src/egl/main/eglapi.h
> +++ b/src/egl/main/eglapi.h
> @@ -80,6 +80,11 @@ typedef EGLBoolean (*DestroyImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLI
>  typedef EGLBoolean (*SwapBuffersRegionNOK_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLint numRects, const EGLint *rects);
>  #endif
> 
> +#ifdef EGL_MESA_create_image
> +typedef EGLBoolean (*QueryImageIntel_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *image, EGLint attribute, EGLint *value);
> +#endif
> +
> +
>  /**
>   * The API dispatcher jumps through these functions
>   */
> @@ -141,6 +146,10 @@ struct _egl_api
>  #ifdef EGL_NOK_swap_region
>     SwapBuffersRegionNOK_t SwapBuffersRegionNOK;
>  #endif
> +
> +#ifdef EGL_MESA_create_image
> +   QueryImageIntel_t QueryImageMESA;
> +#endif
>  };
> 
>  #endif /* EGLAPI_INCLUDED */
> diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c
> index 8cdeaf6..2564b81 100644
> --- a/src/mesa/drivers/dri/intel/intel_regions.c
> +++ b/src/mesa/drivers/dri/intel/intel_regions.c
> @@ -194,6 +194,25 @@ intel_region_alloc(struct intel_context *intel,
>     return region;
>  }
> 
> +GLboolean
> +intel_region_flink(struct intel_context *intel,
> +                  struct intel_region *region,
> +                  uint32_t target_context, uint32_t *name)

How about a comment on this function explaining what it does?


> +{
> +   if (region->name == 0) {
> +      if (drm_intel_bo_flink(region->buffer, &region->name))
> +        return GL_FALSE;
> +
> +      region->screen = intel->intelScreen;
> +      _mesa_HashInsert(intel->intelScreen->named_regions,
> +                      region->name, region);
> +   }
> +
> +   *name = region->name;
> +
> +   return GL_TRUE;
> +}
> +
>  struct intel_region *
>  intel_region_alloc_for_handle(struct intel_context *intel,
>                               GLuint cpp,
> diff --git a/src/mesa/drivers/dri/intel/intel_regions.h b/src/mesa/drivers/dri/intel/intel_regions.h
> index 2459c9a..dac9d84 100644
> --- a/src/mesa/drivers/dri/intel/intel_regions.h
> +++ b/src/mesa/drivers/dri/intel/intel_regions.h
> @@ -87,6 +87,11 @@ intel_region_alloc_for_handle(struct intel_context *intel,
>                               GLuint width, GLuint height, GLuint pitch,
>                               unsigned int handle, const char *name);
> 
> +GLboolean
> +intel_region_flink(struct intel_context *intel,
> +                  struct intel_region *region,
> +                  uint32_t target_context, uint32_t *name);
> +
>  void intel_region_reference(struct intel_region **dst,
>                              struct intel_region *src);
> 
> diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
> index 15a465c..611a98a 100644
> --- a/src/mesa/drivers/dri/intel/intel_screen.c
> +++ b/src/mesa/drivers/dri/intel/intel_screen.c
> @@ -206,11 +206,86 @@ intel_destroy_image(__DRIimage *image)
>      FREE(image);
>  }
> 
> +static __DRIimage *
> +intel_create_image(__DRIcontext *context,
> +                  int width, int height, int format,
> +                  unsigned int use,
> +                  void *loaderPrivate)
> +{
> +   __DRIimage *image;
> +   struct intel_context *intel = context->driverPrivate;
> +   int cpp;
> +
> +   image = CALLOC(sizeof *image);
> +   if (image == NULL)
> +      return NULL;
> +
> +   switch (format) {
> +   case __DRI_IMAGE_FORMAT_RGB565:
> +      image->format = MESA_FORMAT_RGB565;
> +      image->internal_format = GL_RGB;
> +      image->data_type = GL_UNSIGNED_BYTE;
> +      break;
> +   case __DRI_IMAGE_FORMAT_XRGB8888:
> +      image->format = MESA_FORMAT_XRGB8888;
> +      image->internal_format = GL_RGB;
> +      image->data_type = GL_UNSIGNED_BYTE;
> +      break;
> +   case __DRI_IMAGE_FORMAT_ARGB8888:
> +      image->format = MESA_FORMAT_ARGB8888;
> +      image->internal_format = GL_RGBA;
> +      image->data_type = GL_UNSIGNED_BYTE;
> +      break;
> +   default:
> +      free(image);
> +      return NULL;
> +   }
> +
> +   image->data = loaderPrivate;
> +   cpp = _mesa_get_format_bytes(image->format);
> +
> +   image->region =
> +      intel_region_alloc(intel, I915_TILING_NONE,
> +                        cpp, width, height, GL_TRUE);
> +   if (image->region == NULL) {
> +      FREE(image);
> +      return NULL;
> +   }
> +
> +   return image;
> +}
> +
> +
> +
> +static GLboolean
> +intel_query_image(__DRIimage *image,
> +                 int *format, uint32_t *handle, int *pitch)
> +{
> +   switch (image->format) {
> +   case MESA_FORMAT_RGB565:
> +      *format = __DRI_IMAGE_FORMAT_RGB565;
> +      break;
> +   case MESA_FORMAT_XRGB8888:
> +      *format = __DRI_IMAGE_FORMAT_XRGB8888;
> +      break;
> +   case MESA_FORMAT_ARGB8888:
> +      *format = __DRI_IMAGE_FORMAT_ARGB8888;
> +      break;

Default case?


> +   }
> +
> +   *handle = image->region->buffer->handle;
> +   *pitch = image->region->pitch;
> +
> +   return GL_TRUE;
> +}
> +
>  static struct __DRIimageExtensionRec intelImageExtension = {
>      { __DRI_IMAGE, __DRI_IMAGE_VERSION },
>      intel_create_image_from_name,
>      intel_create_image_from_renderbuffer,
>      intel_destroy_image,
> +    intel_create_image,
> +    intel_query_image
>  };
> 
>  static const __DRIextension *intelScreenExtensions[] = {
> --
> 1.7.0.1
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
> .
> 



More information about the mesa-dev mailing list