diff options
author | John Stultz <john.stultz@linaro.org> | 2018-05-31 17:37:21 -0700 |
---|---|---|
committer | John Stultz <john.stultz@linaro.org> | 2018-06-14 10:47:14 -0700 |
commit | df35a81f49c9c0ed4fa9e2f00b1b99ccd36a8407 (patch) | |
tree | 245c98cf4027088973f8d09e29bb9fed2819f823 | |
parent | 53cb4ef4da1ad4c3cb1d138cf8d05f988b304a0d (diff) |
drm_hwcomposer: platformhisi: Add support for importing DRM_FORMAT_YVU420 buffers
When trying to play fullscreen video, I started seeing import
errors, which were caused by us trying to call drmModeAddFB2()
with fmt DRM_FORMAT_YVU420 but only setting the a single set of
handle/pitch/offset values.
In the kernel, the framebuffer_check() function would then fail
with "no buffer object handle for plane 1" since we only passed
one plane in.
Thus this patch calculates and sets the pitch/offset values for
the separate planes in the single gem_handle buffer.
Many thanks to Stefan Schake and Rob Herring for helping me
understand some of the subtleties of image plans vs display
planes, etc.
Change-Id: I2d9bdfc66c504e6446a4f9c6287ab675201afa30
Signed-off-by: John Stultz <john.stultz@linaro.org>
-rw-r--r-- | platformhisi.cpp | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/platformhisi.cpp b/platformhisi.cpp index f8b4412..d4428d0 100644 --- a/platformhisi.cpp +++ b/platformhisi.cpp @@ -31,6 +31,7 @@ #include <hardware/gralloc.h> #include "gralloc_priv.h" +#define MALI_ALIGN(value, base) (((value) + ((base)-1)) & ~((base)-1)) namespace android { @@ -84,17 +85,43 @@ int HisiImporter::ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) { int32_t fmt = ConvertHalFormatToDrm(hnd->req_format); if (fmt < 0) - return fmt; + return fmt; memset(bo, 0, sizeof(hwc_drm_bo_t)); bo->width = hnd->width; bo->height = hnd->height; bo->format = fmt; bo->usage = hnd->usage; + bo->pitches[0] = hnd->byte_stride; bo->gem_handles[0] = gem_handle; bo->offsets[0] = 0; + switch (fmt) { + case DRM_FORMAT_YVU420: { + int align = 128; + if (hnd->usage & + (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) + align = 16; + int adjusted_height = MALI_ALIGN(hnd->height, 2); + int y_size = adjusted_height * hnd->byte_stride; + int vu_stride = MALI_ALIGN(hnd->byte_stride / 2, align); + int v_size = vu_stride * (adjusted_height / 2); + + /* V plane*/ + bo->gem_handles[1] = gem_handle; + bo->pitches[1] = vu_stride; + bo->offsets[1] = y_size; + /* U plane */ + bo->gem_handles[2] = gem_handle; + bo->pitches[2] = vu_stride; + bo->offsets[2] = y_size + v_size; + break; + } + default: + break; + } + ret = drmModeAddFB2(drm_->fd(), bo->width, bo->height, bo->format, bo->gem_handles, bo->pitches, bo->offsets, &bo->fb_id, 0); if (ret) { |