From: Zhigang Gong <zhigang.g...@linux.intel.com> Glamor need a function to create a texture from a BO allocated by using libdrm directly in DDX layer. EGL image extension API eglCreateImageKHR does support this function, but that extension only support one colore format - ARGB32 which is not sufficent for us. I discussed this in the mail list and KRH suggest me to extent GBM to support more color formats should be better. I took his advice and decide to use gbm bo to create image. Now before extent the color formats, I have to add a new API to the create a gbo from a name. This commit is for that purpose.
Signed-off-by: Zhigang Gong <zhigang.g...@linux.intel.com> --- src/gbm/backends/dri/gbm_dri.c | 87 ++++++++++++++++++++++++++++++++++------ src/gbm/main/gbm.c | 14 ++++++ src/gbm/main/gbm.h | 6 +++ src/gbm/main/gbmint.h | 4 ++ 4 files changed, 98 insertions(+), 13 deletions(-) diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c index 9de8cb6..d78cf5f 100644 --- a/src/gbm/backends/dri/gbm_dri.c +++ b/src/gbm/backends/dri/gbm_dri.c @@ -284,6 +284,22 @@ gbm_dri_bo_create_from_egl_image(struct gbm_device *gbm, return &bo->base.base; } +static int +gbm_dri_match_format(enum gbm_bo_format format, int *dri_format) +{ + switch (format) { + case GBM_BO_FORMAT_XRGB8888: + *dri_format = __DRI_IMAGE_FORMAT_XRGB8888; + break; + case GBM_BO_FORMAT_ARGB8888: + *dri_format = __DRI_IMAGE_FORMAT_ARGB8888; + break; + default: + return -1; + } + return 0; +} + static struct gbm_bo * gbm_dri_bo_create(struct gbm_device *gbm, uint32_t width, uint32_t height, @@ -296,23 +312,15 @@ gbm_dri_bo_create(struct gbm_device *gbm, bo = calloc(1, sizeof *bo); if (bo == NULL) - return NULL; + goto fail; bo->base.base.gbm = gbm; bo->base.base.width = width; bo->base.base.height = height; - switch (format) { - case GBM_BO_FORMAT_XRGB8888: - dri_format = __DRI_IMAGE_FORMAT_XRGB8888; - break; - case GBM_BO_FORMAT_ARGB8888: - dri_format = __DRI_IMAGE_FORMAT_ARGB8888; - break; - default: - return NULL; - } - + if (gbm_dri_match_format(format, &dri_format) != 0) + goto fail; + if (usage & GBM_BO_USE_SCANOUT) dri_use |= __DRI_IMAGE_USE_SCANOUT; if (usage & GBM_BO_USE_CURSOR_64X64) @@ -323,8 +331,9 @@ gbm_dri_bo_create(struct gbm_device *gbm, width, height, dri_format, dri_use, bo); + if (bo->image == NULL) - return NULL; + goto fail; dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_HANDLE, &bo->base.base.handle.s32); @@ -332,8 +341,59 @@ gbm_dri_bo_create(struct gbm_device *gbm, (int *) &bo->base.base.pitch); return &bo->base.base; + +fail: + + if (bo) + free(bo); + return NULL; } +static struct gbm_bo * +gbm_dri_bo_create_from_name(struct gbm_device *gbm, + uint32_t width, uint32_t height, + enum gbm_bo_format format, int name, + int pitch) +{ + struct gbm_dri_device *dri = gbm_dri_device(gbm); + struct gbm_dri_bo *bo; + int dri_format; + + bo = calloc(1, sizeof *bo); + if (bo == NULL) + goto fail; + + bo->base.base.gbm = gbm; + bo->base.base.width = width; + bo->base.base.height = height; + + if (gbm_dri_match_format(format, &dri_format) != 0) + goto fail; + + bo->image = + dri->image->createImageFromName(dri->screen, + width, height, + dri_format, name, pitch, + bo); + if (bo->image == NULL) + goto fail; + + dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_HANDLE, + &bo->base.base.handle.s32); + dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE, + (int *) &bo->base.base.pitch); + + return &bo->base.base; + +fail: + + if (bo) + free(bo); + return NULL; + +} + + static void dri_destroy(struct gbm_device *gbm) { @@ -358,6 +418,7 @@ dri_device_create(int fd) dri->base.base.fd = fd; dri->base.base.bo_create = gbm_dri_bo_create; dri->base.base.bo_create_from_egl_image = gbm_dri_bo_create_from_egl_image; + dri->base.base.bo_create_from_name = gbm_dri_bo_create_from_name; dri->base.base.is_format_supported = gbm_dri_is_format_supported; dri->base.base.bo_destroy = gbm_dri_bo_destroy; dri->base.base.destroy = dri_destroy; diff --git a/src/gbm/main/gbm.c b/src/gbm/main/gbm.c index 8440b2c..93e06f3 100644 --- a/src/gbm/main/gbm.c +++ b/src/gbm/main/gbm.c @@ -177,6 +177,20 @@ gbm_bo_create(struct gbm_device *gbm, } GBM_EXPORT struct gbm_bo * +gbm_bo_create_from_name(struct gbm_device *gbm, + uint32_t width, uint32_t height, + enum gbm_bo_format format, int name, + int pitch) +{ + if (width == 0 || height == 0) + return NULL; + + return gbm->bo_create_from_name(gbm, width, height, format, name, pitch); +} + + + +GBM_EXPORT struct gbm_bo * gbm_bo_create_from_egl_image(struct gbm_device *gbm, void *egl_dpy, void *egl_image, uint32_t width, uint32_t height, diff --git a/src/gbm/main/gbm.h b/src/gbm/main/gbm.h index 05d2292..aeed0df 100644 --- a/src/gbm/main/gbm.h +++ b/src/gbm/main/gbm.h @@ -82,6 +82,12 @@ gbm_bo_create(struct gbm_device *gbm, enum gbm_bo_format format, uint32_t flags); struct gbm_bo * +gbm_bo_create_from_name(struct gbm_device *gbm, + uint32_t width, uint32_t height, + enum gbm_bo_format format, int name, + int pitch); + +struct gbm_bo * gbm_bo_create_from_egl_image(struct gbm_device *gbm, void *egl_dpy, void *egl_img, uint32_t width, uint32_t height, diff --git a/src/gbm/main/gbmint.h b/src/gbm/main/gbmint.h index fb8db80..1aab789 100644 --- a/src/gbm/main/gbmint.h +++ b/src/gbm/main/gbmint.h @@ -60,6 +60,10 @@ struct gbm_device { void *egl_dpy, void *egl_img, uint32_t width, uint32_t height, uint32_t usage); + struct gbm_bo *(*bo_create_from_name)(struct gbm_device *gbm, + uint32_t width, uint32_t height, + enum gbm_bo_format format, int name, + int pitch); void (*bo_destroy)(struct gbm_bo *bo); }; -- 1.7.4.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev