Module: Mesa Branch: main Commit: 3922bd59760e82d6da4bb9d063c5854349120f03 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=3922bd59760e82d6da4bb9d063c5854349120f03
Author: Roman Stratiienko <r.stratiie...@gmail.com> Date: Wed Oct 4 00:59:17 2023 +0300 u_gralloc: Extract common code from fallback gralloc ... to reuse it later in QCOM gralloc. Signed-off-by: Roman Stratiienko <r.stratiie...@gmail.com> Tested-by: tarsin <yuanqingxiang...@163.com> Acked-by: Chia-I Wu <olva...@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25410> --- src/util/u_gralloc/meson.build | 1 + src/util/u_gralloc/u_gralloc_fallback.c | 163 ++--------------------------- src/util/u_gralloc/u_gralloc_internal.c | 179 ++++++++++++++++++++++++++++++++ src/util/u_gralloc/u_gralloc_internal.h | 10 ++ 4 files changed, 196 insertions(+), 157 deletions(-) diff --git a/src/util/u_gralloc/meson.build b/src/util/u_gralloc/meson.build index 14e2cd0d115..e706ca46538 100644 --- a/src/util/u_gralloc/meson.build +++ b/src/util/u_gralloc/meson.build @@ -9,6 +9,7 @@ options_for_u_gralloc = [] files_u_gralloc = files( 'u_gralloc.c', + 'u_gralloc_internal.c', 'u_gralloc_fallback.c', 'u_gralloc_cros_api.c', ) diff --git a/src/util/u_gralloc/u_gralloc_fallback.c b/src/util/u_gralloc/u_gralloc_fallback.c index e478b9040fd..ba21c207bbf 100644 --- a/src/util/u_gralloc/u_gralloc_fallback.c +++ b/src/util/u_gralloc/u_gralloc_fallback.c @@ -23,121 +23,6 @@ struct fallback_gralloc { gralloc_module_t *gralloc_module; }; -enum chroma_order { - YCbCr, - YCrCb, -}; - -struct droid_yuv_format { - /* Lookup keys */ - int native; /* HAL_PIXEL_FORMAT_ */ - enum chroma_order chroma_order; /* chroma order is {Cb, Cr} or {Cr, Cb} */ - int chroma_step; /* Distance in bytes between subsequent chroma pixels. */ - - /* Result */ - int fourcc; /* DRM_FORMAT_ */ -}; - -/* The following table is used to look up a DRI image FourCC based - * on native format and information contained in android_ycbcr struct. */ -static const struct droid_yuv_format droid_yuv_formats[] = { - /* Native format, YCrCb, Chroma step, DRI image FourCC */ - {HAL_PIXEL_FORMAT_YCbCr_420_888, YCbCr, 2, DRM_FORMAT_NV12}, - {HAL_PIXEL_FORMAT_YCbCr_420_888, YCbCr, 1, DRM_FORMAT_YUV420}, - {HAL_PIXEL_FORMAT_YCbCr_420_888, YCrCb, 1, DRM_FORMAT_YVU420}, - {HAL_PIXEL_FORMAT_YV12, YCrCb, 1, DRM_FORMAT_YVU420}, - /* HACK: See droid_create_image_from_prime_fds() and - * https://issuetracker.google.com/32077885. */ - {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, YCbCr, 2, DRM_FORMAT_NV12}, - {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, YCbCr, 1, DRM_FORMAT_YUV420}, - {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, YCrCb, 1, DRM_FORMAT_YVU420}, - {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, YCrCb, 1, DRM_FORMAT_AYUV}, - {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, YCrCb, 1, DRM_FORMAT_XYUV8888}, -}; - -static int -get_fourcc_yuv(int native, enum chroma_order chroma_order, int chroma_step) -{ - for (int i = 0; i < ARRAY_SIZE(droid_yuv_formats); ++i) - if (droid_yuv_formats[i].native == native && - droid_yuv_formats[i].chroma_order == chroma_order && - droid_yuv_formats[i].chroma_step == chroma_step) - return droid_yuv_formats[i].fourcc; - - return -1; -} - -static bool -is_yuv(int native) -{ - for (int i = 0; i < ARRAY_SIZE(droid_yuv_formats); ++i) - if (droid_yuv_formats[i].native == native) - return true; - - return false; -} - -static int -get_format_bpp(int native) -{ - int bpp; - - switch (native) { - case HAL_PIXEL_FORMAT_RGBA_FP16: - bpp = 8; - break; - case HAL_PIXEL_FORMAT_RGBA_8888: - case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: - /* - * HACK: Hardcode this to RGBX_8888 as per cros_gralloc hack. - * TODO: Remove this once https://issuetracker.google.com/32077885 is - * fixed. - */ - case HAL_PIXEL_FORMAT_RGBX_8888: - case HAL_PIXEL_FORMAT_BGRA_8888: - case HAL_PIXEL_FORMAT_RGBA_1010102: - bpp = 4; - break; - case HAL_PIXEL_FORMAT_RGB_565: - bpp = 2; - break; - default: - bpp = 0; - break; - } - - return bpp; -} - -/* createImageFromFds requires fourcc format */ -static int -get_fourcc(int native) -{ - switch (native) { - case HAL_PIXEL_FORMAT_RGB_565: - return DRM_FORMAT_RGB565; - case HAL_PIXEL_FORMAT_BGRA_8888: - return DRM_FORMAT_ARGB8888; - case HAL_PIXEL_FORMAT_RGBA_8888: - return DRM_FORMAT_ABGR8888; - case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: - /* - * HACK: Hardcode this to RGBX_8888 as per cros_gralloc hack. - * TODO: Remove this once https://issuetracker.google.com/32077885 is - * fixed. - */ - case HAL_PIXEL_FORMAT_RGBX_8888: - return DRM_FORMAT_XBGR8888; - case HAL_PIXEL_FORMAT_RGBA_FP16: - return DRM_FORMAT_ABGR16161616F; - case HAL_PIXEL_FORMAT_RGBA_1010102: - return DRM_FORMAT_ABGR2101010; - default: - mesa_logw("unsupported native buffer format 0x%x", native); - } - return -1; -} - /* returns # of fds, and by reference the actual fds */ static unsigned get_native_buffer_fds(const native_handle_t *handle, int fds[3]) @@ -163,9 +48,7 @@ fallback_gralloc_get_yuv_info(struct u_gralloc *gralloc, { struct fallback_gralloc *gr = (struct fallback_gralloc *)gralloc; gralloc_module_t *gr_mod = gr->gralloc_module; - enum chroma_order chroma_order; struct android_ycbcr ycbcr; - int drm_fourcc = 0; int num_fds = 0; int fds[3]; int ret; @@ -191,43 +74,9 @@ fallback_gralloc_get_yuv_info(struct u_gralloc *gralloc, } gr_mod->unlock(gr_mod, hnd->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(hnd->hal_format, chroma_order, ycbcr.chroma_step); - if (drm_fourcc == -1) { - mesa_logw("unsupported YUV format, native = %x, chroma_order = %s, " - "chroma_step = %zu", - hnd->hal_format, chroma_order == YCbCr ? "YCbCr" : "YCrCb", - ycbcr.chroma_step); - return -EINVAL; - } - - out->drm_fourcc = drm_fourcc; - out->modifier = DRM_FORMAT_MOD_INVALID; - - out->num_planes = ycbcr.chroma_step == 2 ? 2 : 3; - /* 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. */ - out->offsets[0] = (size_t)ycbcr.y; - /* We assume here that all the planes are located in one DMA-buf. */ - if (chroma_order == YCrCb) { - out->offsets[1] = (size_t)ycbcr.cr; - out->offsets[2] = (size_t)ycbcr.cb; - } else { - out->offsets[1] = (size_t)ycbcr.cb; - out->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. */ - out->strides[0] = ycbcr.ystride; - out->strides[1] = out->strides[2] = ycbcr.cstride; + ret = bufferinfo_from_ycbcr(&ycbcr, hnd, out); + if (ret) + return ret; /* * Since this is EGL_NATIVE_BUFFER_ANDROID don't assume that @@ -258,7 +107,7 @@ fallback_gralloc_get_buffer_info(struct u_gralloc *gralloc, int stride = 0; int fds[3]; - if (is_yuv(hnd->hal_format)) { + if (is_hal_format_yuv(hnd->hal_format)) { int ret = fallback_gralloc_get_yuv_info(gralloc, hnd, out); /* * HACK: https://issuetracker.google.com/32077885 @@ -282,13 +131,13 @@ fallback_gralloc_get_buffer_info(struct u_gralloc *gralloc, assert(num_planes == 1); - drm_fourcc = get_fourcc(hnd->hal_format); + drm_fourcc = get_fourcc_from_hal_format(hnd->hal_format); if (drm_fourcc == -1) { mesa_loge("Failed to get drm_fourcc"); return -EINVAL; } - stride = hnd->pixel_stride * get_format_bpp(hnd->hal_format); + stride = hnd->pixel_stride * get_hal_format_bpp(hnd->hal_format); if (stride == 0) { mesa_loge("Failed to calcuulate stride"); return -EINVAL; diff --git a/src/util/u_gralloc/u_gralloc_internal.c b/src/util/u_gralloc/u_gralloc_internal.c new file mode 100644 index 00000000000..c6452022150 --- /dev/null +++ b/src/util/u_gralloc/u_gralloc_internal.c @@ -0,0 +1,179 @@ +/* + * Mesa 3-D graphics library + * + * Copyright © 2021, Google Inc. + * Copyright (C) 2023 Roman Stratiienko (r.stratiie...@gmail.com) + * SPDX-License-Identifier: MIT + */ + +#include "u_gralloc_internal.h" + +#include <hardware/gralloc.h> +#include <errno.h> + +#include "drm-uapi/drm_fourcc.h" +#include "util/log.h" + +enum chroma_order { + YCbCr, + YCrCb, +}; + +struct droid_yuv_format { + /* Lookup keys */ + int native; /* HAL_PIXEL_FORMAT_ */ + enum chroma_order chroma_order; /* chroma order is {Cb, Cr} or {Cr, Cb} */ + int chroma_step; /* Distance in bytes between subsequent chroma pixels. */ + + /* Result */ + int fourcc; /* DRM_FORMAT_ */ +}; + +/* The following table is used to look up a DRI image FourCC based + * on native format and information contained in android_ycbcr struct. */ +static const struct droid_yuv_format droid_yuv_formats[] = { + /* Native format, YCrCb, Chroma step, DRI image FourCC */ + {HAL_PIXEL_FORMAT_YCbCr_420_888, YCbCr, 2, DRM_FORMAT_NV12}, + {HAL_PIXEL_FORMAT_YCbCr_420_888, YCbCr, 1, DRM_FORMAT_YUV420}, + {HAL_PIXEL_FORMAT_YCbCr_420_888, YCrCb, 1, DRM_FORMAT_YVU420}, + {HAL_PIXEL_FORMAT_YV12, YCrCb, 1, DRM_FORMAT_YVU420}, + /* HACK: See droid_create_image_from_prime_fds() and + * https://issuetracker.google.com/32077885. */ + {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, YCbCr, 2, DRM_FORMAT_NV12}, + {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, YCbCr, 1, DRM_FORMAT_YUV420}, + {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, YCrCb, 1, DRM_FORMAT_YVU420}, + {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, YCrCb, 1, DRM_FORMAT_AYUV}, + {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, YCrCb, 1, DRM_FORMAT_XYUV8888}, +}; + +static int +get_fourcc_yuv(int native, enum chroma_order chroma_order, int chroma_step) +{ + for (int i = 0; i < ARRAY_SIZE(droid_yuv_formats); ++i) + if (droid_yuv_formats[i].native == native && + droid_yuv_formats[i].chroma_order == chroma_order && + droid_yuv_formats[i].chroma_step == chroma_step) + return droid_yuv_formats[i].fourcc; + + return -1; +} + +bool +is_hal_format_yuv(int native) +{ + for (int i = 0; i < ARRAY_SIZE(droid_yuv_formats); ++i) + if (droid_yuv_formats[i].native == native) + return true; + + return false; +} + +int +get_hal_format_bpp(int native) +{ + int bpp; + + switch (native) { + case HAL_PIXEL_FORMAT_RGBA_FP16: + bpp = 8; + break; + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: + /* + * HACK: Hardcode this to RGBX_8888 as per cros_gralloc hack. + * TODO: Remove this once https://issuetracker.google.com/32077885 is + * fixed. + */ + case HAL_PIXEL_FORMAT_RGBX_8888: + case HAL_PIXEL_FORMAT_BGRA_8888: + case HAL_PIXEL_FORMAT_RGBA_1010102: + bpp = 4; + break; + case HAL_PIXEL_FORMAT_RGB_565: + bpp = 2; + break; + default: + bpp = 0; + break; + } + + return bpp; +} + +int +get_fourcc_from_hal_format(int native) +{ + switch (native) { + case HAL_PIXEL_FORMAT_RGB_565: + return DRM_FORMAT_RGB565; + case HAL_PIXEL_FORMAT_BGRA_8888: + return DRM_FORMAT_ARGB8888; + case HAL_PIXEL_FORMAT_RGBA_8888: + return DRM_FORMAT_ABGR8888; + case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: + /* + * HACK: Hardcode this to RGBX_8888 as per cros_gralloc hack. + * TODO: Remove this once https://issuetracker.google.com/32077885 is + * fixed. + */ + case HAL_PIXEL_FORMAT_RGBX_8888: + return DRM_FORMAT_XBGR8888; + case HAL_PIXEL_FORMAT_RGBA_FP16: + return DRM_FORMAT_ABGR16161616F; + case HAL_PIXEL_FORMAT_RGBA_1010102: + return DRM_FORMAT_ABGR2101010; + default: + mesa_logw("unsupported native buffer format 0x%x", native); + } + return -1; +} + +/* Fill the bufferinfo structure using the information from the + * android_ycbcr struct. fds[] are not filled by this function. + */ +int +bufferinfo_from_ycbcr(const struct android_ycbcr *ycbcr, + struct u_gralloc_buffer_handle *hnd, + struct u_gralloc_buffer_basic_info *out) +{ + enum chroma_order 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. */ + int drm_fourcc = + get_fourcc_yuv(hnd->hal_format, chroma_order, ycbcr->chroma_step); + + if (drm_fourcc == -1) { + mesa_logw("unsupported YUV format, native = %x, chroma_order = %s, " + "chroma_step = %zu", + hnd->hal_format, chroma_order == YCbCr ? "YCbCr" : "YCrCb", + ycbcr->chroma_step); + return -EINVAL; + } + + out->drm_fourcc = drm_fourcc; + + out->num_planes = ycbcr->chroma_step == 2 ? 2 : 3; + /* 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. */ + out->offsets[0] = (size_t)ycbcr->y; + /* We assume here that all the planes are located in one DMA-buf. */ + if (chroma_order == YCrCb) { + out->offsets[1] = (size_t)ycbcr->cr; + out->offsets[2] = (size_t)ycbcr->cb; + } else { + out->offsets[1] = (size_t)ycbcr->cb; + out->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. */ + out->strides[0] = ycbcr->ystride; + out->strides[1] = out->strides[2] = ycbcr->cstride; + + return 0; +} diff --git a/src/util/u_gralloc/u_gralloc_internal.h b/src/util/u_gralloc/u_gralloc_internal.h index 906253fd482..277def2c629 100644 --- a/src/util/u_gralloc/u_gralloc_internal.h +++ b/src/util/u_gralloc/u_gralloc_internal.h @@ -37,6 +37,16 @@ extern struct u_gralloc *u_gralloc_imapper_api_create(void); #endif extern struct u_gralloc *u_gralloc_fallback_create(void); +/* Helpers for legacy grallocs */ +struct android_ycbcr; + +bool is_hal_format_yuv(int native); +int get_hal_format_bpp(int native); +int get_fourcc_from_hal_format(int native); +int bufferinfo_from_ycbcr(const struct android_ycbcr *ycbcr, + struct u_gralloc_buffer_handle *hnd, + struct u_gralloc_buffer_basic_info *out); + #ifdef __cplusplus } #endif