summaryrefslogtreecommitdiff
path: root/src/egl/drivers
diff options
context:
space:
mode:
authorRoman Stratiienko <r.stratiienko@gmail.com>2020-08-20 18:31:17 +0300
committerMarge Bot <eric+marge@anholt.net>2021-06-30 16:50:44 +0000
commit5d3e64f10548035aa29e90d44fead6ba048220d9 (patch)
tree1d79b443bc0f5841242b337346864a49bba180bd /src/egl/drivers
parent974c58b317d1185a53c6753faf24bedae859fa0b (diff)
egl: android: prepare code for adding more buffer_info getters
Instead of calling droid_create_image_ for every gralloc implementation, create struct buffer_info which contains all required field for invoking createImageFromDmaBufs2() and let the getters to fill this structure. Since createImageFromDmaBufs2() is called now only once, the code looks cleaner and more robust. Signed-off-by: Roman Stratiienko <r.stratiienko@gmail.com> Reviewed-by: Yiwei Zhang <zzyiwei@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6045>
Diffstat (limited to 'src/egl/drivers')
-rw-r--r--src/egl/drivers/dri2/platform_android.c238
1 files changed, 134 insertions, 104 deletions
diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
index a200615f9e3..988e0a3c181 100644
--- a/src/egl/drivers/dri2/platform_android.c
+++ b/src/egl/drivers/dri2/platform_android.c
@@ -187,114 +187,120 @@ get_native_buffer_name(struct ANativeWindowBuffer *buf)
}
#endif /* HAVE_DRM_GRALLOC */
-static __DRIimage *
-droid_create_image_from_prime_fds_yuv(_EGLDisplay *disp,
- struct ANativeWindowBuffer *buf,
- void *priv,
- int num_fds, int fds[3])
+struct buffer_info {
+ uint32_t drm_fourcc;
+ int num_planes;
+ int fds[4];
+ uint64_t modifier;
+ int offsets[4];
+ int pitches[4];
+ enum __DRIYUVColorSpace yuv_color_space;
+ enum __DRISampleRange sample_range;
+ enum __DRIChromaSiting horizontal_siting;
+ enum __DRIChromaSiting vertical_siting;
+};
+
+static int
+get_yuv_buffer_info(_EGLDisplay *disp,
+ struct ANativeWindowBuffer *buf,
+ struct buffer_info *out_buf_info)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct android_ycbcr ycbcr;
- int offsets[3];
- int pitches[3];
enum chroma_order chroma_order;
- int fourcc;
+ int drm_fourcc = 0;
+ int num_fds = 0;
+ int fds[3];
int ret;
- unsigned error;
+
+ num_fds = get_native_buffer_fds(buf, fds);
+ if (num_fds == 0)
+ return -EINVAL;
if (!dri2_dpy->gralloc->lock_ycbcr) {
_eglLog(_EGL_WARNING, "Gralloc does not support lock_ycbcr");
- return NULL;
+ return -EINVAL;
}
memset(&ycbcr, 0, sizeof(ycbcr));
ret = dri2_dpy->gralloc->lock_ycbcr(dri2_dpy->gralloc, buf->handle,
0, 0, 0, 0, 0, &ycbcr);
if (ret) {
- /* HACK: See droid_create_image_from_prime_fds() and
+ /* HACK: See native_window_buffer_get_buffer_info() and
* https://issuetracker.google.com/32077885.*/
if (buf->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)
- return NULL;
+ return -EAGAIN;
_eglLog(_EGL_WARNING, "gralloc->lock_ycbcr failed: %d", ret);
- return NULL;
+ return -EINVAL;
}
dri2_dpy->gralloc->unlock(dri2_dpy->gralloc, buf->handle);
+ chroma_order = ((size_t)ycbcr.cr < (size_t)ycbcr.cb) ? YCrCb : YCbCr;
+
+ /* .chroma_step is the byte distance between the same chroma channel
+ * values of subsequent pixels, assumed to be the same for Cb and Cr. */
+ drm_fourcc = get_fourcc_yuv(buf->format, chroma_order, ycbcr.chroma_step);
+ if (drm_fourcc == -1) {
+ _eglLog(_EGL_WARNING, "unsupported YUV format, native = %x, chroma_order = %s, chroma_step = %d",
+ buf->format, chroma_order == YCbCr ? "YCbCr" : "YCrCb", ycbcr.chroma_step);
+ return -EINVAL;
+ }
+
/* When lock_ycbcr's usage argument contains no SW_READ/WRITE flags
* it will return the .y/.cb/.cr pointers based on a NULL pointer,
* so they can be interpreted as offsets. */
- offsets[0] = (size_t)ycbcr.y;
+ out_buf_info->offsets[0] = (size_t)ycbcr.y;
/* We assume here that all the planes are located in one DMA-buf. */
- if ((size_t)ycbcr.cr < (size_t)ycbcr.cb) {
- chroma_order = YCrCb;
- offsets[1] = (size_t)ycbcr.cr;
- offsets[2] = (size_t)ycbcr.cb;
+ if (chroma_order == YCrCb) {
+ out_buf_info->offsets[1] = (size_t)ycbcr.cr;
+ out_buf_info->offsets[2] = (size_t)ycbcr.cb;
} else {
- chroma_order = YCbCr;
- offsets[1] = (size_t)ycbcr.cb;
- offsets[2] = (size_t)ycbcr.cr;
+ out_buf_info->offsets[1] = (size_t)ycbcr.cb;
+ out_buf_info->offsets[2] = (size_t)ycbcr.cr;
}
/* .ystride is the line length (in bytes) of the Y plane,
* .cstride is the line length (in bytes) of any of the remaining
* Cb/Cr/CbCr planes, assumed to be the same for Cb and Cr for fully
* planar formats. */
- pitches[0] = ycbcr.ystride;
- pitches[1] = pitches[2] = ycbcr.cstride;
-
- /* .chroma_step is the byte distance between the same chroma channel
- * values of subsequent pixels, assumed to be the same for Cb and Cr. */
- fourcc = get_fourcc_yuv(buf->format, chroma_order, ycbcr.chroma_step);
- if (fourcc == -1) {
- _eglLog(_EGL_WARNING, "unsupported YUV format, native = %x, chroma_order = %s, chroma_step = %d",
- buf->format, chroma_order == YCbCr ? "YCbCr" : "YCrCb", ycbcr.chroma_step);
- return NULL;
- }
+ out_buf_info->pitches[0] = ycbcr.ystride;
+ out_buf_info->pitches[1] = out_buf_info->pitches[2] = ycbcr.cstride;
/*
* Since this is EGL_NATIVE_BUFFER_ANDROID don't assume that
* the single-fd case cannot happen. So handle eithe single
* fd or fd-per-plane case:
*/
- int num_planes = (ycbcr.chroma_step == 2) ? 2 : 3;
+ out_buf_info->num_planes = (ycbcr.chroma_step == 2) ? 2 : 3;
if (num_fds == 1) {
- fds[2] = fds[1] = fds[0];
+ out_buf_info->fds[1] = out_buf_info->fds[0] = fds[0];
+ if (out_buf_info->num_planes == 3)
+ out_buf_info->fds[2] = fds[0];
} else {
- assert(num_fds == num_planes);
- }
-
- return dri2_dpy->image->createImageFromDmaBufs(dri2_dpy->dri_screen,
- buf->width, buf->height, fourcc,
- fds, num_planes, pitches, offsets,
- EGL_ITU_REC601_EXT,
- EGL_YUV_NARROW_RANGE_EXT,
- EGL_YUV_CHROMA_SITING_0_EXT,
- EGL_YUV_CHROMA_SITING_0_EXT,
- &error,
- priv);
+ assert(num_fds == out_buf_info->num_planes);
+ out_buf_info->fds[0] = fds[0];
+ out_buf_info->fds[1] = fds[1];
+ out_buf_info->fds[2] = fds[2];
+ }
+
+ out_buf_info->drm_fourcc = drm_fourcc;
+
+ return 0;
}
-static __DRIimage *
-droid_create_image_from_prime_fds(_EGLDisplay *disp,
- struct ANativeWindowBuffer *buf,
- void *priv)
+static int
+native_window_buffer_get_buffer_info(_EGLDisplay *disp,
+ struct ANativeWindowBuffer *buf,
+ struct buffer_info *out_buf_info)
{
- struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
- int pitches[4] = { 0 }, offsets[4] = { 0 };
- unsigned error;
- int num_fds;
+ int num_planes = 0;
+ int drm_fourcc = 0;
+ int pitch = 0;
int fds[3];
- num_fds = get_native_buffer_fds(buf, fds);
- if (num_fds == 0)
- return NULL;
-
if (is_yuv(buf->format)) {
- __DRIimage *image;
-
- image = droid_create_image_from_prime_fds_yuv(
- disp, buf, priv, num_fds, fds);
+ int ret = get_yuv_buffer_info(disp, buf, out_buf_info);
/*
* HACK: https://issuetracker.google.com/32077885
* There is no API available to properly query the IMPLEMENTATION_DEFINED
@@ -302,8 +308,8 @@ droid_create_image_from_prime_fds(_EGLDisplay *disp,
* an arbitrary YCbCr 4:2:0 or RGBX_8888, with the latter being recognized
* by lock_ycbcr failing.
*/
- if (image || buf->format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)
- return image;
+ if (ret != -EAGAIN)
+ return ret;
}
/*
@@ -311,29 +317,30 @@ droid_create_image_from_prime_fds(_EGLDisplay *disp,
* color compression state buffer, but the rest of the code isn't ready
* yet to deal with modifiers:
*/
- assert(num_fds == 1);
+ num_planes = get_native_buffer_fds(buf, fds);
+ if (num_planes == 0)
+ return -EINVAL;
+
+ assert(num_planes == 1);
- const int fourcc = get_fourcc(buf->format);
- if (fourcc == -1) {
+ drm_fourcc = get_fourcc(buf->format);
+ if (drm_fourcc == -1) {
_eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
- return NULL;
+ return -EINVAL;
}
- pitches[0] = buf->stride * get_format_bpp(buf->format);
- if (pitches[0] == 0) {
+ pitch = buf->stride * get_format_bpp(buf->format);
+ if (pitch == 0) {
_eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
- return NULL;
+ return -EINVAL;
}
- return dri2_dpy->image->createImageFromDmaBufs(dri2_dpy->dri_screen,
- buf->width, buf->height, fourcc,
- fds, num_fds, pitches, offsets,
- EGL_ITU_REC601_EXT,
- EGL_YUV_NARROW_RANGE_EXT,
- EGL_YUV_CHROMA_SITING_0_EXT,
- EGL_YUV_CHROMA_SITING_0_EXT,
- &error,
- priv);
+ out_buf_info->num_planes = num_planes;
+ out_buf_info->drm_fourcc = drm_fourcc;
+ out_buf_info->pitches[0] = pitch;
+ out_buf_info->fds[0] = fds[0];
+
+ return 0;
}
/* More recent CrOS gralloc has a perform op that fills out the struct below
@@ -359,36 +366,32 @@ struct cros_gralloc0_buffer_info {
int stride[4];
};
-static __DRIimage *
-droid_create_image_from_cros_info(_EGLDisplay *disp,
- struct ANativeWindowBuffer *buf,
- void* priv)
+static int
+cros_get_buffer_info(_EGLDisplay *disp,
+ struct ANativeWindowBuffer *buf,
+ struct buffer_info *out_buf_info)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct cros_gralloc0_buffer_info info;
- unsigned error;
if (strcmp(dri2_dpy->gralloc->common.name, cros_gralloc_module_name) == 0 &&
dri2_dpy->gralloc->perform &&
- dri2_dpy->image->base.version >= 15 &&
- dri2_dpy->image->createImageFromDmaBufs2 != NULL &&
dri2_dpy->gralloc->perform(dri2_dpy->gralloc,
CROS_GRALLOC_DRM_GET_BUFFER_INFO,
buf->handle, &info) == 0) {
- return dri2_dpy->image->createImageFromDmaBufs2(dri2_dpy->dri_screen,
- buf->width, buf->height,
- info.drm_fourcc, info.modifier,
- info.fds, info.num_fds,
- info.stride, info.offset,
- EGL_ITU_REC601_EXT,
- EGL_YUV_FULL_RANGE_EXT,
- EGL_YUV_CHROMA_SITING_0_EXT,
- EGL_YUV_CHROMA_SITING_0_EXT,
- &error,
- priv);
+ out_buf_info->drm_fourcc = info.drm_fourcc;
+ out_buf_info->modifier = info.modifier;
+ out_buf_info->num_planes = info.num_fds;
+ for (int i = 0; i < out_buf_info->num_planes; i++) {
+ out_buf_info->fds[i] = info.fds[i];
+ out_buf_info->offsets[i] = info.offset[i];
+ out_buf_info->pitches[i] = info.stride[i];
+ }
+
+ return 0;
}
- return NULL;
+ return -EINVAL;
}
static __DRIimage *
@@ -396,13 +399,40 @@ droid_create_image_from_native_buffer(_EGLDisplay *disp,
struct ANativeWindowBuffer *buf,
void *priv)
{
- __DRIimage *dri_image;
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct buffer_info buf_info = {.modifier = DRM_FORMAT_MOD_INVALID};
+ unsigned error;
- dri_image = droid_create_image_from_cros_info(disp, buf, priv);
- if (dri_image)
- return dri_image;
+ do {
+ if (!cros_get_buffer_info(disp, buf, &buf_info))
+ break;
+
+ if (!native_window_buffer_get_buffer_info(disp, buf, &buf_info))
+ break;
+
+ return NULL;
+ } while (0);
- return droid_create_image_from_prime_fds(disp, buf, priv);
+ if (dri2_dpy->image->base.version >= 15 &&
+ dri2_dpy->image->createImageFromDmaBufs2 != NULL) {
+ return dri2_dpy->image->createImageFromDmaBufs2(dri2_dpy->dri_screen,
+ buf->width, buf->height, buf_info.drm_fourcc, buf_info.modifier,
+ buf_info.fds, buf_info.num_planes,
+ buf_info.pitches, buf_info.offsets,
+ buf_info.yuv_color_space, buf_info.sample_range,
+ buf_info.horizontal_siting, buf_info.vertical_siting,
+ &error,
+ priv);
+ } else {
+ return dri2_dpy->image->createImageFromDmaBufs(dri2_dpy->dri_screen,
+ buf->width, buf->height, buf_info.drm_fourcc,
+ buf_info.fds, buf_info.num_planes,
+ buf_info.pitches, buf_info.offsets,
+ buf_info.yuv_color_space, buf_info.sample_range,
+ buf_info.horizontal_siting, buf_info.vertical_siting,
+ &error,
+ priv);
+ }
}
static EGLBoolean