summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Stultz <john.stultz@linaro.org>2018-05-31 17:37:21 -0700
committerJohn Stultz <john.stultz@linaro.org>2018-06-14 10:47:14 -0700
commitdf35a81f49c9c0ed4fa9e2f00b1b99ccd36a8407 (patch)
tree245c98cf4027088973f8d09e29bb9fed2819f823
parent53cb4ef4da1ad4c3cb1d138cf8d05f988b304a0d (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.cpp29
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) {